Calibration task with JTextField scrollable

I have a form with a lot of text fields, and some of these text fields can contain very long lines. To do this, I made these text fields scrollable with this code:

JScrollPane scroll = new JScrollPane(textField); scroll.setPreferredSize(new Dimension((int)textField.getPreferredSize().getWidth(), (int)textField.getPreferredSize().getHeight() * 2)); 

Then I put the scroll in my form using the GridBagLayout.

The second line in my example is required to display the scroller. But this has a drawback. When I resize the window to fit all the text in the text field, I scroll through the disappearances, leaving me only two times higher than the other text field, which looks ridiculous. How can I do all this and show the normal size of the text box after the scroller?

EDIT

You can use the following as a demo code to reproduce the problem:

 import javax.swing.*; import java.awt.*; public class ScrollTextDemo extends JFrame{ public ScrollTextDemo(){ super(); this.setPreferredSize(new Dimension(500, 300)); JPanel panel = new JPanel(); panel.setLayout(new GridBagLayout()); JTextField textField = new JTextField("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); textField.setCursor(new Cursor(0)); textField.setEditable(false); JScrollPane scroll = new JScrollPane(textField); scroll.setPreferredSize(new Dimension(70, 40) ); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.5; gbc.insets = new Insets(5, 5, 0, 5); panel.add(scroll,gbc); //let add one more text field without scroll bar to compare JTextField textField2 = new JTextField("abc"); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 2; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.5; gbc.insets = new Insets(5, 5, 0, 5); panel.add(textField2,gbc); this.add(panel); } public static void main(String args[]){ ScrollTextDemo demo = new ScrollTextDemo(); demo.pack(); demo.setVisible(true); } } 
+4
source share
2 answers

For this, in the absence of a good SSCCE , I think that you have not provided any restrictions for filling, which is used for

Used when the display area of ​​a component is larger than the size of the requested component to determine how and how to resize the component. Valid values ​​(defined as GridBagConstraints constants) include NONE (default), HORIZONTAL (make the component wide enough to fill its horizontal display area, but not change its height), VERTICAL (make the component high enough to fill its display area by vertically, but do not change its width), and BOTH (make the component completely fill the display area).

So you should add something like this to GridBagConstraints

constraintsGridBag.fill = GridBagConstraints.HORIZONTAL;

This will only allow you to expand HORIZONTALLY not in both directions.

** EDIT: Regarding the added code **

Never specify setPreferredSize (...) for any component in Swing. Let the layout manager you use, take care of this. Remove all setPreferredSize (...) objects, allowing them to remain at their normal size when resized.

* EDIT 2: *

Code to tell you what I say:

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.*; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; public class GridBagTest extends JFrame { private JPanel topPanel; private JPanel bottomPanel; public GridBagTest() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; //gbc.fill = GridBagConstraints.HORIZONTAL; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 0.8; // Setting TOP PANEL. topPanel = new JPanel(); topPanel.setLayout(new GridBagLayout()); GridBagConstraints constraintsTopPanel = new GridBagConstraints(); constraintsTopPanel.gridwidth = 2; // Specifies that this component will take two columns. constraintsTopPanel.gridheight = 1; // specifies that the component will take one row. /* * fill with HORIZONTAL, means the component upon resize, will * only expand along the X-Axis. */ constraintsTopPanel.fill = GridBagConstraints.NONE; constraintsTopPanel.insets = new Insets(5, 5, 5, 5); constraintsTopPanel.ipadx = 2; constraintsTopPanel.ipady = 2; constraintsTopPanel.weightx = 0.3; constraintsTopPanel.weighty = 0.2; constraintsTopPanel.gridx = 0; constraintsTopPanel.gridy = 0; JTextField tfield1 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10); topPanel.add(tfield1, constraintsTopPanel); constraintsTopPanel.gridx = 2; constraintsTopPanel.gridy = 0; final JTextField tfield2 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10); topPanel.add(tfield2, constraintsTopPanel); constraintsTopPanel.gridx = 4; constraintsTopPanel.gridy = 0; JTextField tfield3 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10); topPanel.add(tfield3, constraintsTopPanel); topPanel.setBackground(Color.WHITE); add(topPanel, gbc); constraintsTopPanel.gridx = 0; constraintsTopPanel.gridy = 2; constraintsTopPanel.gridwidth = 6; // Specifies that this component will take two columns. constraintsTopPanel.gridheight = 1; // specifies that the component will take one row. JButton button = new JButton("REMOVE"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { topPanel.remove(tfield2); topPanel.revalidate(); topPanel.repaint(); } }); topPanel.add(button, constraintsTopPanel); //Setting BOTTOM PANEL. bottomPanel = new JPanel(); bottomPanel.setLayout(new BorderLayout()); bottomPanel.setBackground(Color.DARK_GRAY); JLabel label3 = new JLabel("I am a new JLABEL for the bottom JPanel", JLabel.CENTER); label3.setForeground(Color.WHITE); bottomPanel.add(label3, BorderLayout.CENTER); gbc.weighty = 0.2; add(bottomPanel, gbc); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); pack(); setVisible(true); } public static void main(String... args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new GridBagTest(); } }); } } 
+4
source

Well, the best I have seems to be ugly in code, but it does exactly what I need for textField. Below is a sample code from the original question. I would be grateful for any ideas on how to make this better:

 import javax.swing.*; import java.awt.*; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; public class ScrollTextDemo extends JFrame{ public ScrollTextDemo(){ super(); this.setPreferredSize(new Dimension(500, 300)); JPanel panel = new JPanel(); panel.setLayout(new GridBagLayout()); JTextField textField = new JTextField("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); textField.setCursor(new Cursor(0)); textField.setEditable(false); JScrollPane scroll = new JScrollPane(textField, JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.5; //gbc.ipady = 20;//gives some room for scroll to appear and don't hide text area under the scroll. gbc.insets = new Insets(5, 5, 0, 5); panel.add(scroll,gbc); //let add one more text field without scroll bar to compare JTextField textField2 = new JTextField("bbbbbbbb"); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 2; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.5; gbc.insets = new Insets(5, 5, 0, 5); panel.add(textField2,gbc); scroll.addComponentListener( new ScrollTextComponentListener(scroll, textField2)); this.add(panel); } public static void main(String args[]){ ScrollTextDemo demo = new ScrollTextDemo(); demo.pack(); demo.setVisible(true); } } class ScrollTextComponentListener implements ComponentListener { private boolean scrollVisible; private JScrollPane scroll; private JComponent compareComponent; public ScrollTextComponentListener(JScrollPane scroll, JComponent compareComponent) { this.scroll = scroll; this.compareComponent = compareComponent; } private boolean isScrollVisible() { return scroll.getHorizontalScrollBar().getModel().getExtent() != scroll.getHorizontalScrollBar().getModel().getMaximum(); } private void setScrollSize(){ boolean scrollVisible = isScrollVisible(); if (scrollVisible){ scroll.setPreferredSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()*2)); //also had to set both min and max sizes, because only preffered size didn't always work scroll.setMinimumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()*2)); scroll.setMaximumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()*2)); } else { scroll.setPreferredSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight())); scroll.setMinimumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight())); scroll.setMaximumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight())); } this.scrollVisible = scrollVisible; } @Override public void componentResized(ComponentEvent e) { if (isScrollVisible() != scrollVisible) setScrollSize(); } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentShown(ComponentEvent e) { setScrollSize(); } @Override public void componentHidden(ComponentEvent e) { } 

}

0
source

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


All Articles