1

I'm making a simple GUI and have a problem. This is my code :

JFrame jFrame = new JFrame();
jFrame.setTitle("Simple Editor");
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setLocation(50,50);
jFrame.setResizable(true);

Box box = new Box(BoxLayout.Y_AXIS);

JTextArea jTextArea = new JTextArea();
jTextArea.setPreferredSize(new Dimension(470,500));

JLabel jLabel = new JLabel();

box.add(jTextArea);
box.add(jLabel);

jLabel.setText("Font type : " + Main.fontType + " font size : " + Main.size 
         + " background color : " + Main.backgroundColor
         + " font color : " + Main.fontColor);

jFrame.setContentPane(box);
jFrame.pack();
jFrame.setVisible(true);

When I typing something in JTextArea, text in JLabel is moving. I can't figure out how to solve this. Maybe some component between them? Any advice and help is welcome.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Cosaquee
  • 724
  • 1
  • 6
  • 22
  • 1
    1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). 2) See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Jun 07 '15 at 15:14

2 Answers2

3

This looks like an artifact of how the Box is calculating sizes and locations. Note that some components and layout managers do not use setPreferredSize, or only take it as a hint, or use it as only one part of a computation, or etc. so it cannot be depended upon as a reliable method to set the size of a component.

In this case, I would hypothesize what is going on is something like: BoxLayout generally uses minimum/maximum sizes, not preferred sizes, and the min/max of a JTextArea is computed based on its text content. As the text changes, the size is recalculated so the layout changes too.

In general if you have a text area, you should put it in a JScrollPane instead:

Box box = new Box(BoxLayout.Y_AXIS);

JTextArea jTextArea = new JTextArea();

JScrollPane jScrollPane = new JScrollPane(jTextArea);
jScrollPane.getViewport().setPreferredSize(new Dimension(470,500));

JLabel jLabel = new JLabel();

box.add(jScrollPane);
box.add(jLabel);

This way when the text content changes in the JTextArea it can simply do its thing, recalculating its size, and flow out the side of the scroll pane.

Also see How to Use Scroll Panes, How to Use Text Areas.


Per Andrew's comment, here are a couple ways to set the initial size of the scroll pane which are perhaps more reliable than setting the viewport's preferred size explicitly:

// specify rows & columns
JTextArea jTextArea = new JTextArea(20, 20);

// specify preferred scrollable viewport size
JTextArea jTextArea = new JTextArea() {
    @Override
    public Dimension getPreferredScrollableViewportSize() {
        return new Dimension(470,500);
    }
};
Community
  • 1
  • 1
Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • `JTextArea jTextArea = new JTextArea(); .. jScrollPane.getViewport().setPreferredSize(new Dimension(470,500));` should be (adjust numbers to need) `JTextArea jTextArea = new JTextArea(4,20); ..` See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Jun 07 '15 at 16:01
  • @AndrewThompson Thanks for the suggestion. The actual reason to do that is that the `JTextArea` rows and columns are (apparently, as I had to go and check) used indirectly by `JScrollPane` to calculate its size. The Q&A you're linking to doesn't say that and quite frankly does an extremely poor job explaining why `setPreferredSize` is actually bad. – Radiodef Jun 07 '15 at 16:51
1
jTextArea.addKeyListener(new KeyAdapter() {
    @Override
    public void keyTyped(KeyEvent e) {
        jLabel.setText(jTextArea.getText());
    }
});

where,

  • jTextArea - your name object of JTextArea class
  • jLabel - your name object of JLabel class

You add text in the textarea and text in the label is changing. I think, this code help you to decide your problem.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142