gpt4 book ai didi

java - Swing 组件 setSize()/setBounds() 问题

转载 作者:搜寻专家 更新时间:2023-11-01 03:11:30 25 4
gpt4 key购买 nike

内容


  1. 概览
  2. 示例代码
  3. 问题截图

1。问题概述


因此,我正在为我正在开发的复杂程序编写 GUI,并且我厌倦了尝试让组件在调整窗口大小时正确缩放。

起初我在 jframe 和每个 jpanel 中使用了几个布局来尝试正确放置组件并适本地缩放它们。自然地,我受够了它们,我开始尝试动态缩放和设置组件的 x、y 位置(这要容易得多 :D)。

基本上,我试图将屏幕分成三个部分,左边距 (JSplitPane)、中间 (JTabbedPane) 和右边距 (JSplitPane)。我认为此时内部组件并不重要。 主要问题是尽管我使用 setBounds() 将 x,y 放在右侧并将大小设置为总宽度的 21%,但右侧的 JSplitPane 会在整个窗口上缩放。它似乎与其他面板的交互很奇怪。


2。示例代码


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);
}
}

3。截图


Screenshot1 Screenshot2

最佳答案

I don't think the internal components matter at this point.

Should I avoid the use of set[Preferred|Maximum|Minimum]Size methods in Java Swing? 中所述, 没有东西会离事实很远。布局的正确使用依赖于组件的首选尺寸。该尺寸是根据内容仔细计算的。如您的示例所示,第二次猜测注定要失败。

相反,添加组件和 pack() 框架。在下面的示例中,中心面板返回一个任意结果以显示 pack() 是如何工作的。

附录:@mKorbel 有益地引用了另外两点:

  • Swing GUI 对象应该event dispatch thread 上构造和操作.

  • 另请参阅此 example展示了如何在 invokeLater() 中使用 setDividerLocation()

enter image description here

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);
}
});
}
}

关于java - Swing 组件 setSize()/setBounds() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9117458/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com