Word wrapping a JLabe/JTextArea in a JPanel in a JScrollPane - java

In my application, I need to word wrap Labels, which are contained in a JPanel (with GridBagLayout), which in turn is contained in a JScrollPane, which is contained in a resizable JFrame. The text should always be as wide as the Scrollpane allows(i.e. be completly visible at once). I tried multiple things already:
Putting tags around the text.
Result: Nothing
Putting on the Text
Result: Wraps, but with static width (does not respond to the Frame being resized) (duh)
Putting on the Text
Result: Nothing
Using a JTextArea, as in https://stackoverflow.com/a/26426585/4936150
Result: Appears to work at first, when the width of the Frame is increased, the words get "unwrapped" (so they are all on one line), but when the width is decreased afterwards, it will stay that way and not "wrap back". Also, weirdly doesn't work in the Nimbus L&F
Implementing Scrollable on the JPanel and returning true from getScrollableTracksViewportWidth()
Result: Works, but I DO want it to scroll horizontally if the Frame is too small for other Components
For reference, here is the source for my Panel class, without any wrapping:
public class ProgPanel extends JPanel {
/**
* Create the panel.
*/
public ProgPanel() {
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0};
gridBagLayout.rowHeights = new int[]{59, 0, 0};
gridBagLayout.columnWeights = new double[]{1.0};
gridBagLayout.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
setLayout(gridBagLayout);
JLabel lblName = new JLabel("Long, long text taht needs to be wrapped, because it is displayed in a very big font on a kindof small screen, bla bla bla bhlergh lol rofl 1337");
GridBagConstraints gbc_lblName = new GridBagConstraints();
gbc_lblName.gridwidth = 2;
gbc_lblName.anchor = GridBagConstraints.WEST;
gbc_lblName.insets = new Insets(0, 0, 5, 0);
gbc_lblName.gridwidth = 1;
gbc_lblName.gridx = 0;
gbc_lblName.gridy = 0;
add(lblName, gbc_lblName);
lblName.setBorder(new EmptyBorder(10, 5, 0, 10));
lblName.setIconTextGap(10);
lblName.setIcon(new ImageIcon("someicon.png"));
lblName.setFont(getFont().deriveFont(Font.BOLD+Font.ITALIC, 48));
}
}
EDIT: Here is the implementation using a JTextArea, which will only grow in width, but not shrink: https://pastebin.com/egMXfwK1 (Pastebin due to long length and tedious SO formatting)
EDIT2: Here are some pictures showing the issue: http://imgur.com/a/mhtV9

Related

JLabel multiline with HTML

I have a JLabel that I would like to contain a text that can go over multiple lines, and resizes if the window changes shape.
I've looked this up and most people seem to recommend wrapping the label text in HTML. This however does not make new lines for me.
My label is located in a JPanel and I suspect that the problem may be that my panel has misconfigured its border, and so the label text just continues beyond the panel border.
here is how the label looks inside the status panel
Here are the settings of the panel:
private final JPanel statusPanel = new JPanel(new FlowLayout());
statusPanel.setBackground(Color.white);
statusPanel.add(latestOrdreLabel);
this.add(statusPanel, new GridBagConstraints(0, 0, 6, 1, 1.0, 1.0
, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0));
Then the label is set up like this:
private final JLabel latestOrdreLabelResult = new JLabel();
String latestOrdreStatus = getBean().getLatestOrdreStatus(etelOrderInterface.getOrderId());
latestOrdreLabelResult.setText("<html>"+latestOrdreStatus+"</html>");
statusPanel.add(latestOrdreLabelResult);
In HTML, to down line your'e need to use <br/> instead of \n.
You can to use in replace String method, for example:
latestOrdreStatus.replace("\n", "<br/>");
You just need to resize the label.

Java JTextField view from the Right

I have a JTextField that I'm trying to get to automatically view from the Right (Not align to the right), so if the text is to long for the JTextField it will display the last characters in the String instead of the beginning.
Ive been searching for ages trying to locate an answer but keep coming up with aligning.
The 2 images below show what i get and what I'm after, the text is "123456789_123", the JTextField is only big enough to contain the "123456789" but i want to see the "56789_123" instead without having to focus on the field. (i can use something other than a JTextField if needed, tried a JTextArea but had the same issue).
What i Get
What I'm after
I can not just make the Field bigger as I'm restricted by other Objects in my program. Usually the text fits fine but every now and then its too big.
Found a work around.
you create a JScrollPane, make its vertical and horizontal bars invisible by setting there dimensions to 0,0. then scroll to end using 'setValue' to max.
hope this helps anyone trying to do something similar.
JTextArea editArea2 = new JTextArea(5,5);
editArea2.setText("123456789_12345");
editArea2.setAlignmentX(CENTER_ALIGNMENT);
asd = new Dimension();
asd.height = 20;
asd.width = 70;
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(editArea2);
scrollPane.setMinimumSize(asd);
scrollPane.setMaximumSize(asd);
scrollPane.getVerticalScrollBar().setPreferredSize (new Dimension(0,0));
scrollPane.getHorizontalScrollBar().setPreferredSize (new Dimension(0,0));
scrollPane.getVerticalScrollBar().setMinimumSize(new Dimension(0, 0));
scrollPane.getVerticalScrollBar().setMinimumSize(new Dimension(0, 0));
scrollPane.getVerticalScrollBar().setMaximumSize(new Dimension(0, 0));
scrollPane.getVerticalScrollBar().setMaximumSize(new Dimension(0, 0));
scrollPane.getHorizontalScrollBar().setValue( scrollPane.getHorizontalScrollBar().getMaximum() );

Why does this GridBagLayout have unused empty space and how can I get rid of it?

So I have a JPanel that is split into 2 other separate JPanels (although this is mostly irrelevant). On the left side I have a GridBagLayout that I have organized to have a JLabel at the top, and a JTextArea below it, however the JTextArea isn't directly beneath the JLabel. Instead there is this empty space and I can't figure out why it's there or how to fix it. I'm fairly new to Java in general and GridBagLayout so I could be missing something, but I've tried several things to get it to work. I have the code for this below along with a visual representation of what it's doing. Any help is appreciated.
CODE
//LEFT SIDE
GridBagConstraints leftGBC = new GridBagConstraints();
JPanel leftSide = new JPanel(new GridBagLayout());
leftSide.setBorder(new EmptyBorder(inset, inset, inset, inset));
Font titleFont = bb5.comfortaa.deriveFont(Font.PLAIN, 16f);
leftGBC.gridx = 0;
leftGBC.gridy = 0;
leftGBC.weightx = 1;
leftGBC.weighty = 1;
leftGBC.anchor = GridBagConstraints.NORTH;
JLabel leftTitle = new JLabel("Objective");
leftTitle.setFont(titleFont);
leftTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.BLACK));
leftGBC.fill = GridBagConstraints.HORIZONTAL;
leftSide.add(leftTitle, leftGBC);
leftGBC.gridy = 1;
leftGBC.anchor = GridBagConstraints.NORTH;
JTextArea objectiveArea = new JTextArea(objectiveText);
objectiveArea.setBackground(leftTitle.getBackground());
objectiveArea.setEditable(false);
objectiveArea.setFocusable(false);
objectiveArea.setFont(bb5.samsung1.deriveFont(16f));
objectiveArea.setLineWrap(true);
objectiveArea.setWrapStyleWord(true);
leftSide.add(objectiveArea, leftGBC);
VISUAL
leftGBC.weightx = 1;
leftGBC.weighty = 1;
Read the section from the Swing tutorial How to use GridBagLayout. The tutorial explains how the weightx/weighty constraints work. Those values indicate how to allocate "extra space" to each cell. So it would appear that both the label and text area getting extra space. I would guess you want 0 for the label.
If this doesn't help (and in the future when you ask a question), post a proper SSCCE that demonstrates the problem.

GridBagLayout Assistance

I've tried all combinations and looked at all the documentation but I can't figure out how to use GridBagLayout.
I've got 3 components in a JPanel with GridBagLayout being the LayoutManager of the JPanel and using GridBagConstraints on the 3 components.
With the current code (as shown below) the 3 elements appear on the panel properly. The issue is that the first component is a JLabel which sometimes is quite long, if this is the case then it will expand and make the other 2 components smaller.
My objective is to have a JPanel with a GridBagLayout of 1 row and 4 columns, where the first element takes up the first 2 columns, and the other 2 elements take up the remaining 2, and that these elements to do not expand out of their columns.
private static void setConstraints(GridBagConstraints constraints, int gridx, int gridy, int weightx, Insets insets) {
constraints.gridx = gridx;
constraints.weightx = weightx;
constraints.insets = insets;
}
gridBagLayout = new GridBagLayout();
constraints = new GridBagConstraints();
centerPanel = new JPanel(gridBagLayout);
constraints.fill = GridBagConstraints.HORIZONTAL;
fileNameLabel = new JLabel("Resolving: '" + EngineHelpers.trimStringToFitPanel(urlTextField.getText(), 70) + "'");
setConstraints(constraints, 0, 0, 2, new Insets(0, 5, 5, 0));
gridBagLayout.setConstraints(fileNameLabel, constraints);
progressBar = new JProgressBar();
progressBar.setStringPainted(true);
setConstraints(constraints, 1, 0, 1, new Insets(0, 5, 5, 0));
gridBagLayout.setConstraints(progressBar, constraints);
cancelDownloadButton = new JButton("Cancel");
setConstraints(constraints, 2, 0, 1, new Insets(0, 0, 0, 0));
gridBagLayout.setConstraints(cancelDownloadButton, constraints);
centerPanel.add(fileNameLabel);
centerPanel.add(progressBar);
centerPanel.add(cancelDownloadButton);
Thanks in advance everyone, sorry for the stupid question!
You probably want weightx set to 0 for both the button and progress bar. For the label, set the weight to 1. This will keep the button and progress bar from expanding at all and let the progress bar take all the extra space.
Also set gridwidth on the progress bar constraints to 2 so it actually uses 2 columns.
Finally, depending on where centerPanel is placed, it may not actual expand to fill the container. If centerPanel is being placed in a parent with a BorderLayout, it should expand. To make sure, you can add a border with centerPanel.setBorder(BorderFactory.createLineBorder(Color.RED)) for debugging. This can also be useful on the button, label and progress bars too.

JList border disappears on scrolling

I've five lists (enclosed in a jscrollpane) added to a jpanel in a group layout. The problem with the lists is that when a scrollbar appears automatically, the border on the bottom/top disappears (lists 2,3,4). How do I make sure that all lists look the same w.r.t border just like the first/last lists?
I've tried setting viewportborder using setViewPortBroder, but it doesn't change things much. 2,3,4 appear with light border while the rest of the lists have double borders.
EDIT
Adding code sample:
Each list you see is created using this code:
MyJList jList = new MyJList(value);
jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jList.setModel(listModel);
jList.setMinimumSize(new Dimension(135, 300));
jList.setMaximumSize(new Dimension(135, 300));
jList.clearSelection();
jList.setSelectionBackground(Color.darkGray);
jList.setSelectionForeground(Color.white);
jList.setBorder(new LineBorder(Color.darkGray, 1));
jList.setFixedCellHeight(30);
jList.setFixedCellWidth(100);
Font font = jList.getFont();
jList.addListSelectionListener(new ListListener());
return jList;
MyList is an extension of JList. It does nothing special, other than storing some domain related metadata. And, then lists are added to the middle panel like this:
private void layoutLists(JLabel[] labels, JList[] lists) {
panel.removeAll();
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
JScrollPane[] jScrollPanes = new JScrollPane[lists.length];
for (int index = 0; index < lists.length; index++) {
jScrollPanes[index] = new JScrollPane(lists[index]);
jScrollPanes[index].setBorder(BorderFactory.createEmptyBorder());
jScrollPanes[index].setMinimumSize(new Dimension(135, 300));
jScrollPanes[index].setMaximumSize(new Dimension(135, 300));
jScrollPanes[index].setPreferredSize(new Dimension(135, 300));
}
for (int index = 0; index < labels.length; index++) {
gbc.gridx = index;
gbc.gridy = 0;
gbc.insets = new Insets(8, 8, 8, 8);
panel.add(labels[index], gbc);
gbc.gridy = 1;
if (index == labels.length - 1) {
gbc.insets = new Insets(8, 8, 8, 13);
}
panel.add(jScrollPanes[index], gbc);
}}
The explanation of the top/bottom part of the inner (JList) border not being visible is that ... they are not visible if the vertical scrollBar appears (the list is scrolled off)
If you insist, either:
switch the borders - empty on the list itself and lineBorder on the scrollPane or
set the viewportBorderProperty of the scrollPane to the lineBorder
Beware: it's not recommended to fiddle with the default LAF settings - where-to or not the components have a border should be left to the ui to guarantee consistent visuals across your application. Nor does it look exactly good to have the left border line beside (either outside or inside) the scrollPane's vertical scrollbar.
Edit
Just noticed that you already tried the second option (and are not satisfied with the result :-) But then: where do you want the vertical border line if the scrollBar is visible? Anyway, back to the beware: the outcome is highly LAF dependent ...

Categories