所以我正在编写一个用于我正在开发的复杂程序的GUI,我厌倦了在调整窗口大小时尝试正确扩展组件。
起初我在jframe中使用了几个布局,并且每个jpanel都尝试正确放置组件并适当地缩放它们。当然,我厌倦了他们,我开始尝试缩放并动态设置组件的x,y位置(它更容易:D)。
基本上我试图将屏幕划分为左边距(JSplitPane),中心(JTabbedPane)和右边距(JSplitPane)三个部分。我不认为内部组件在这一点上很重要。 主要问题是正确的JSplitPane在整个窗口上进行缩放,尽管我使用setBounds()将x,y放在右边,并将大小设置为总宽度的21%。它似乎与其他小组互动很奇怪。
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.Dimension;
@SuppressWarnings("deprecation")
public class test extends JFrame implements WindowListener {
/* Constants =========================================================================*/
private final double LEFT_SIZE = .21;
private final double CENTER_SIZE = .58;
private final double RIGHT_SIZE = .21;
private final int TOP_PADDING = 50;
private final int LEFT_PADDING = 4;
private final int RIGHT_PADDING = 4;
private final int BOTTOM_PADDING = 4;
private final int MIN_WIDTH = 640;
private final int MIN_HEIGHT = 480;
public static final String INIT_TITLE = "TestFrame v0.01";
/* End Constants =====================================================================*/
/* Instance Variables ================================================================*/
private int contentWidth;
private int contentHeight;
/* End Instance Variables ============================================================*/
/* Objects ===========================================================================*/
public static test window;
/* Begin Frame Design =========================================================== */
private JSplitPane left;
private JButton button1; private JButton button2;
private JTabbedPane center;
private JPanel panel1; private JPanel panel2;
private JSplitPane right;
private JButton button3; private JButton button4;
/* End Frame Design ============================================================= */
/* End Objects ====================================================================== */
/** Initializes and Places all GUI elements **/
public test ( String windowName ) {
super(windowName); //call parent constructor
this.addWindowListener(this); //adds window event functionality such as close
this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH); //Starts program maximized
this.setMinimumSize(new Dimension(MIN_WIDTH,MIN_HEIGHT));
this.setVisible(true);
this.setMaximumSize(this.getSize());
/* Begin Init JFrame this ------------------------------------------------------------ */
button1 = new JButton("button1");
button2 = new JButton("button2");
left = new JSplitPane(JSplitPane.VERTICAL_SPLIT, button1, button2);
left.setResizeWeight(1);
button3 = new JButton("button3");
button4 = new JButton("button4");
right = new JSplitPane(JSplitPane.VERTICAL_SPLIT, button3, button4);
right.setResizeWeight(.25);
panel1 = new JPanel();
panel2 = new JPanel();
center = new JTabbedPane();
center.addTab("Panel1", panel1);
center.addTab("Panel2", panel2);
this.add(left);
this.add(center);
this.add(right);
this.addComponentListener(new ComponentListener() {
@Override
public void componentResized (ComponentEvent e) {
window.contentWidth = window.getWidth() - window.LEFT_PADDING - window.RIGHT_PADDING;
window.contentHeight = window.getHeight() - window.TOP_PADDING - window.BOTTOM_PADDING;
window.left.setBounds ( 0, 0, (int)(window.contentWidth * window.LEFT_SIZE), window.contentHeight);
window.center.setBounds ( window.left.getWidth(), 0, (int)(window.contentWidth * window.CENTER_SIZE), window.contentHeight);
window.panel1.setBounds ( 0, 0, (int)(window.contentWidth * window.CENTER_SIZE), window.contentHeight);
window.panel2.setBounds ( 0, 0, (int)(window.contentWidth * window.CENTER_SIZE), window.contentHeight);
window.right.setBounds ( window.left.getWidth() + window.center.getWidth(), 0, (int)(window.contentWidth * window.RIGHT_SIZE), window.contentHeight);
}
public void componentHidden (ComponentEvent e) {}
public void componentMoved (ComponentEvent e) {}
public void componentShown (ComponentEvent e) {}
});
/* End Init JFrame this -------------------------------------------------------------- */
}
// window event abstracts
@Override
public void windowClosing (WindowEvent event) { window.dispose(); System.exit(0); }
public void windowClosed (WindowEvent event) {}
public void windowDeiconified (WindowEvent event) {}
public void windowIconified (WindowEvent event) {}
public void windowActivated (WindowEvent event) {}
public void windowDeactivated (WindowEvent event) {}
public void windowOpened (WindowEvent event) {}
public static void main(String[] args){
window = new test(INIT_TITLE);
window.setVisible(true);
}
}
答案 0 :(得分:3)
我认为内部组件在这一点上并不重要。
正如Should I avoid the use of set[Preferred|Maximum|Minimum]Size methods in Java Swing?中所讨论的那样,事实并非如此。正确使用布局依赖组件的首选大小。该尺寸是根据内容仔细计算的。如你的例子所示,第二次猜测注定要失败。
相反,添加组件和pack()
框架。在下面的示例中,中心面板返回任意结果,以显示pack()
的工作方式。
附录:@mKorbel提出的另外两点:
应在event dispatch thread上仅构建和操作Swing GUI对象。
另请参阅此example,了解如何在setDividerLocation()
中使用invokeLater()
。
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import java.awt.Dimension;
import java.awt.EventQueue;
public class Test extends JFrame {
public static final String INIT_TITLE = "TestFrame v0.02";
public static Test window;
private JSplitPane left;
private JTabbedPane center;
private JSplitPane right;
public Test(String windowName) {
super(windowName);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
left = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
new JButton("button1"), new JButton("button2"));
left.setResizeWeight(0.5);
right = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
new JButton("button3"), new JButton("button4"));
right.setResizeWeight(0.5);
center = new JTabbedPane();
center.addTab("Panel1", new MyPanel());
center.addTab("Panel2", new MyPanel());
this.add(left, BorderLayout.WEST);
this.add(center, BorderLayout.CENTER);
this.add(right, BorderLayout.EAST);
this.pack();
this.setLocationByPlatform(true);
this.setVisible(true);
}
private static class MyPanel extends JPanel {
private Dimension d = new Dimension(320, 240);
@Override
public Dimension getPreferredSize() {
return d;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
window = new Test(INIT_TITLE);
window.setVisible(true);
}
});
}
}