Swing task componentSize () / setBounds ()

Content


  • Overview
  • Code example
  • Screenshots of the problem

1. Overview of the problem


So, I am writing a graphical interface for a complex program that I am developing, and I am tired of trying to properly scale the components when the window is resized.

At first, I used several layouts inside jframe, and each jpanel tried to position components correctly and scale them correctly. Naturally, I got tired of them, and I started trying to scale and dynamically set the x, y positions of the components (this is much simpler: D).

I mainly try to split the screen into three fields on the left (JSplitPane), center (JTabbedPane) and right field (JSplitPane). I do not think that internal components matter at this point. The main problem : the correct JSplitPane scales across the window, despite the fact that I used setBounds () to put x, y on the right and set the size to 21% of the total width. It seems to be interacting with other panels.


2. Code Example


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. Screenshots


Screenshothot1Screenshot2

+4
source share
1 answer

I do not think that internal components matter at this point.

As discussed in Should I Avoid Using the [Preferred | Maximum | Minimum] Size in Java Swing? nothing could be further from the truth. The proper use of layouts depends on the preferred size of the component. This size is carefully calculated based on the content. The second guessing, as shown in your example, is doomed to failure.

Add components and a pack() frame instead. In the example below, the center panel returns an arbitrary result to show how pack() does its job.

Appendix: Two additional points that were useful to @mKorbel:

  • Swing GUI objects should only be created and processed in the event dispatch thread .

  • See also this example , which shows how to use setDividerLocation() in invokeLater() .

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); } }); } } 
+3
source

Source: https://habr.com/ru/post/1394446/


All Articles