Как правильно установить минимальные размеры в Java?
для приложения GUI, которое я создаю на Java, у меня есть следующее:
- в JFrame, имеет минимальный размер (300,200)
- A JSplitPane, в котором лежит:
- слева, JScrollPane (содержащий JTree) с минимальным размером (100,0) (я только хочу ограничить ширину до 200)
- справа, JPanel с минимальным размером (200,0)
размер не дает мне никакой проблемы под следующие условия:
- изменение размера JSplitPane полностью влево (до минимального размера JScrollPane), а затем изменение размера окна после
- просто изменение размера окна, в определенной степени
проблема возникает, когда я перемещаю JSplitPane слишком близко вправо, после чего изменение размера окна JPanel в правой части JSplitPane не соответствует минимальной ширине, которую я установил.
Я попытался установить максимальная ширина на JScrollPane, которая, казалось, не помогала вообще.
есть ли что-то с максимальными размерами, которые я должен сделать? Или, может быть, есть способ прикрепить слушателя к одной из панелей, чтобы заставить мое желаемое поведение? В конечном счете, я просто хочу, чтобы правая панель в JSplitPane никогда не была меньше 200px.
вот пример с поведением, которое я испытываю:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
public class ResizeTest
{
private JFrame frame;
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
ResizeTest window = new ResizeTest();
window.frame.setVisible(true);
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
}
public ResizeTest()
{
initialize();
}
private void initialize()
{
frame = new JFrame();
frame.setMinimumSize(new Dimension(300, 200));
frame.setBounds(100,100,450,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridLayout(0, 1, 0, 0));
JSplitPane splitPane = new JSplitPane();
frame.getContentPane().add(splitPane);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setMinimumSize(new Dimension(100, 0));
splitPane.setLeftComponent(scrollPane);
JTree tree = new JTree();
tree.setMinimumSize(new Dimension(100, 0));
scrollPane.setViewportView(tree);
JPanel panel = new JPanel();
panel.setMinimumSize(new Dimension(200, 0));
splitPane.setRightComponent(panel);
}
}
обновление:
боюсь, я не полностью поймите, что нужно сделать в предлагаемых решениях, за исключением того, что setPreferred () и setMinimum/Maximum () лучше избегать.
мой вопрос в ответ на это обучение, каковы мои варианты ограничения разделителя JSplitPane вне использования этих методов? MadProgrammer упомянуто прослушивание события componentResized, но мне нужно немного больше разъяснений относительно того, почему. Я вызываю setDividerLocation () в реакция на это событие?
Я заранее извиняюсь, если добавленный вопрос подразумевается как отдельный вопрос StackOverflow полностью, я могу опубликовать другой и ссылку здесь, если это необходимо.
обновление 2:
просто не регулирует, как пользователь выбирает размер окна и наличие правой панели в JScrollPane является жизнеспособным вариантом? Мне кажется, это стандартная практика.
2 ответов
во-первых, метод setMinimumSize
это предложение LayoutManager
API-интерфейс. Предложение, которое можно проигнорировать.
чтобы иметь возможность даже приблизиться к поддержке этого, вам нужно будет использовать что-то вроде ComponentListener и монитор componentResized событие.
лучшее решение, которое я могу придумать, это использовать LayoutManager
который фактически использует минимальные и максимальные ограничения размера, что-то вроде GridBagLayout
.
использовать это на панели "содержимое" и место, где вы JSplitPane
на это (установка минимального и максимального размера соответственно) затем добавьте панель "содержимое" в рамку.
обновление
Извините, я, вероятно, пропустил что-то действительно очевидное, но я поставил этот маленький тест вместе, надеюсь, что у него есть некоторые идеи, которые помогают :P
public class TestFrameSize extends JFrame {
public TestFrameSize() throws HeadlessException {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(600, 600);
setLocationRelativeTo(null);
setMinimumSize(new Dimension(250, 250));
JLabel left = new JLabel("Left");
JLabel right = new JLabel("Right");
Dimension pSize = new Dimension(100, 100);
Dimension mSize = new Dimension(25, 100);
left.setPreferredSize(pSize);
left.setMinimumSize(mSize);
right.setPreferredSize(pSize);
right.setMinimumSize(mSize);
JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right);
JPanel content = new JPanel(new GridBagLayout());
content.add(pane);
setLayout(new BorderLayout());
add(content);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new TestFrameSize().setVisible(true);
}
}
в этой пример предпочтительный размер содержания JSplitPane
первоначально устанавливается в небольшое кратное предпочтительному размеру компонента в getPreferredSize()
. Обратите внимание, что JSplitPane
станет не меньше минимального размера панели, управляемого прилагаемым Jlabel
.