【问题标题】:Swing component setSize()/setBounds() issueSwing 组件 setSize()/setBounds() 问题
【发布时间】:2012-02-25 09:50:44
【问题描述】:

内容


  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。截图


【问题讨论】:

  • “您可以在此处找到包含 jarfile 的可运行示例。” 不,谢谢。为了尽快获得更好的帮助,请发帖SSCCE
  • “动态设置组件的 x,y 位置(这要容易得多:D)。” 您的麻烦似乎另有说明。
  • @AndrewThompson 这是一个 SSCCE。可运行的示例仅包含几行代码,用于设置框架并计算一些填充元素。这是您需要的大部分代码。
  • @Kronos25 bulk of the code you need 也许对你来说有趣的信息我们大多数人不需要什么,也不需要你的最后评论:-)
  • @Kronos25 "这是一个 SSCCE。可运行的示例只包含几行代码" SSCCE 不需要其他任何东西我>。 “关闭”没有奖品。未来注意事项 - 您正在与 SSCCE 文档的作者交谈。

标签: java swing resize jpanel


【解决方案1】:

我认为目前内部组件并不重要。

正如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()

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

【讨论】:

  • @mKorbel:谢谢!抱歉,我忽略了您的其他有用点;如果您恢复答案,请联系我。
  • 我不想使用这些愚蠢的布局,但似乎没有其他方法:(
  • @trashgod 不,我不想在这里恢复我已删除的帖子,顺便说一句非常好的线程,不是吗,
  • @Kronos25:感谢您转向acceptance。我只能向你保证,使用布局会很多更糟。
猜你喜欢
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多