When typing into JTextArea, text in JLabel moves - java

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.

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

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.

Related

Swing labels won't align properly in BoxLayout

I have a JPanel with several JLabels in it and a JTextPane. I want them to be below each other (so no two two labels on the same line), and aligned to the left. I have tried several things:
Using a BoxLayout with BoxLayout.Y_AXIS works for properly getting all elements below each other. However, while the JTextPane correctly aligns to the left, the JLabels stay centered, even when calling several methods to try and get the alignment to the left (see code below).
Using a GridLayout will correctly put the elements below each other and align them to the left, but then the elements will be vertically spread all over the JPanel with huge spaces between the text lines. I want all elements to be in the top of the panel as far as possible.
private final void init() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JLabel("a"));
final JLabel label = new JLabel();
final JTextPane pane = new JTextPane();
add(label);
add(pane);
// these three lines seem to be ignored
label.setHorizontalAlignment(SwingConstants.LEFT);
label.setAlignmentX(LEFT_ALIGNMENT);
label.setHorizontalTextPosition(SwingConstants.LEFT);
pane.setForeground(Color.RED);
pane.setEditable(false);
}
How can I get this right?
I want them to be below each other (so no two two labels on the same line), and aligned to the left.
You need to set the alignment on all components, even the JTextPane.
add(new JLabel("a"));
How do you expect to change the alignment of that label when you don't have a reference to it?
final JLabel label = new JLabel();
final JTextPane pane = new JTextPane();
add(label);
add(pane);
You don't set the alignment of the above components.
Read the section from the Swing tutorial on Fixing Alignment Problems

Change JTextField height on Swing

I'm trying to fix the height of the "amountField" text field, but I can't.
I would like the height of amountField to have the same height as the JComboBox that it's above, so it looks better.
Right now, the JTextField looks very tall compared with the rest of design.
I've tried everything that I've read in this forum, but nothing seems to work.
I don't know if it's relevant, but this whole JPanel (WithdrawalScreen) is inside another JPanel with BorderLayout. This panel is the center part of it
Thanks
PictureHere
public class WithdrawalScreen extends JPanel {
Public JPanel init() {
this.setLayout(new GridLayout(0,1));
account = new JLabel("account");
accountSelect = new JComboBox(labels);
amount = new JLabel("amount");
amountField = new JTextField("");
submit = new JButton("SUBMIT");
this.add(account);
this.add(accountSelect);
this.add(amount);
this.add(amountField);
this.add(submit);
return this;
}
}
Try creating the Grid Layout with 5 rows and 1 column. I think the height is messed up because you are not setting the constructor arguments properly.
new GridLayout(5,1);
Grid layout will stretch the component and give the same size to all of its components. In order to keep the "default" size of each component, you can use BoxLayout with BoxLayout.Y_AXIS parameter in its constructor. Another way would be to use a dummy-nested JPanel with another layout. Let's say FlowLayout.
JTextField textField = new JTextField(10);
JPanel nestedPanel = new JPanel(new FlowLayout());
nestedPanel.add(textField);
gridLayoutPanel.add(nestedPanel);
JTextField will not be stretched. nestedPanel will be. Do some experiments yourself and you will find the way that fits your needs.
A link that will help you: A visoual guide to Layout Managers.

JComponent partially hidden due to scrollpane in a BoxLayout

I want to add the possibility for my users to add a comment on a form. To display them, I created JPanel inside a simple JScrollPane. I set the layout of this JPanel to BoxLayout because I wish to add them all in only one column and it seemed to be the easiest way by calling BoxLayout.Y_AXIS in the constructor. I also tried GridLayout and GridBagLayout but it was not what I was looking for.
My problem is that when a JPanel has the BoxLayout layout, it's width automatically is the same as it's container, but my container is a JScrollPane and the caret hides the right side of my comment!
You can see the JTextField and a JButton on the bottom left, here's the code on the click event :
private void btnAjoutCommentaireActionPerformed(java.awt.event.ActionEvent evt) {
//I take the text from the JTextField and format it to html
String formattedComment = "<html><br><div style='width:280px;'>" +
txtArCommentaire.getText().replaceAll("\n", "<br>") +
"</div><br></html>";
JLabel label = new JLabel(formattedComment);
//I add a blue border
label.setBorder(new TitledBorder(new EtchedBorder(Color.lightGray, Color.blue), ConfigUser.getCu().toString()));
//this below doesn't work
label.setSize(280, 200);
//I tried adding a JPanel in between but it didn't really worked out
//JPanel panel = new JPanel();
//panel.setLayout(new GridLayout(1, 1));
//panel.setSize(297, 200);
//panel.add(label);
///pnlCommentaire is the JPanel inside the JScrollPane
pnlCommentaire.setLayout(new BoxLayout(pnlCommentaire, BoxLayout.Y_AXIS));
pnlCommentaire.add(label);
pnlCommentaire.revalidate();
pnlCommentaire.repaint();
}
As you can see I tried to adust the size in html using style='width:280px'and on the JLabel using label.setSize(280, 200); but none of them worked.
Do you have any idea on how I could resize this Jlabel?
EDIT :
I added a margin-right property to the div so that I can at least fully see the text in the JLabel but the right border is still hidden.
String formattedComment = "<html><br><div style='width:280px;margin-right:50px;'>" +
txtArCommentaire.getText().replaceAll("\n", "<br>") +
"</div><br></html>";

Swing JPanel Resizing: won't fit the contents of text file - cuts out text

The java application I'm building utilises the Swing framework. I'm new to Swing, and I'm trying to display some text from a file. The problem is that not all my text is displayed using the code below - it is cut off.
The code
So far, I've created a JFrame component to contain everything:
//initial frame that holds everything
frame = new JFrame(WINDOW_NAME);
frame.setSize(new Dimension((SCREEN_WIDTH.intValue()/100)*80, (SCREEN_HEIGHT.intValue()/100)*80));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Within that, I've created a scroll pane to allow the user to read through the contents of the text file by scrolling vertically; it's quite a large text file - a few chapters from a book.
JScrollPane scrollPane = new JScrollPane(contentPane);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setWheelScrollingEnabled(true);
frame.setContentPane(scrollPane);
The scroll pane contains a JPanel object. I've utilised the GridBagLayout layout manager for this. The panel itself holds an EditorPane which I've instantiated with the text file's URL.
JPanel contentPane = new JPanel();
contentPane.setPreferredSize(new Dimension(frame.getWidth(), frame.getHeight()));
buildAndAddComponentsToFrame(contentPane);
private void buildAndAddComponentsToFrame(Container container) {
container.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1.0;
c.weighty = 1.0;
c.insets = new Insets((frame.getHeight()/100)*10, (frame.getWidth()/100)*10, (frame.getHeight()/100)*10, (frame.getWidth()/100)*10);
//create a non-editable editor pane to hold the contents of the religious texts
JEditorPane textContainer = new JEditorPane();
textContainer.setEditable(false);
//TODO load the content of the pane from a URL (local)
File textFile = new File(*my text file*);
try {
textContainer.setPage(textFile.toURI().toURL());
} catch (IOException e) {
e.printStackTrace();
}
container.add(textContainer,c);
}
This works - I'm able to read the contents of the file but not in its entirety: it only shows what it can fit within the height of the JPanel object. I don't want to place the text content within a ScrollPane - but make the JPanel's height be relative to the contents of the text file.
Is there any way to achieve this? I've used the container to make the "text area" appear like a microsoft word document hence the insets - it looks like a paper document in the middle of the jframe - this is intentional.
Thanks for any help - sorry if my explanation was a bit vague. I've added a screenshot to help explain.
You're creating a JPanel, using default FlowLayout, you're forcing its preferred size to some value, and then wondering why it won't get bigger when the JTextPane it holds has text greater than it's size. This is not happening for the mistakes that you're making above.
Suggestions:
Best to place the JTextPane into the JScrollPane, to not constrain the JTextPane's size or preferred size.
Otherwise if you must wrap the JTextPane in a JPanel, give it a JPanel that will expand if its components expand. Use a BorderLayout and add the JTextPane BorderLayout.CENTER. Then place that into a JScrollPane's viewport and if must constrain sizes, do so of the viewport.

Java. Swing. Multiline labels in a JScrollPane

I have a JFrame with JScrollPane in it. I have JPanel inside a scrollPane. And add multiline labels in it.
Everything is ok with multiline labels. I enclose my text in <HTML>..</HTML> tags.
And labels display its wrapped text.
"..." means long multiline text.
The problem is that useless area is displayed in the bottom.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(300, 300));
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
label1.setText("<html>" + "..." + "</html>");
panel.add(label1);
label2.setText("<html>" + "..." + "</html>");
panel.add(label2);
JScrollPane scroll = new JScrollPane(panel);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
frame.setContentPane(scroll);
frame.pack();
frame.setVisible(true);
EDIT.
So I have to set preferred size for inner JPanel. After that scrollPane draws its content(shows scrollbars) as its content has this fixed "inner panel preffered size".
If I won't set preferred size for the panel, JLabels wouldn't wrap the text.
After being layed out by the layout manager inner panel's size grows and became larger than previously set preferred size. Panel grows itself, its ok, I see wrapped text of labels in it. But scrollpane behaves incorrectly. It paints scroll as inner panel is still of prefferred size size. So I need correct resizing behaviour for JScrollPane.
use JTextPane or JEditorPane instead of JPanel contains bunch of JLabels
JTextPane or JEditorPane supporting stylled text or Html <= 3.2 for Java6
theoretically you can use JList, instead of Jlabels, but in this case you have to call for setPreferredScrollableViewportSize(new Dimension) same as for JPanel in the JScrollPane
EDIT
then use Highlighter
use built-in reader/writer for JTextComponents

Categories