JButton over JScrollPane - java

I have such piece of code which shoud add button over JTextArea placed in JScrollPane. Button isn't inside scroll pane!
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(10, 340, 375, 242);
contentPane.add(scrollPane);
JButton btnClean = new JButton();
btnClean.setBounds(340, 341, 26, 23);
contentPane.add(btnClean);
taLog = new JTextArea();
taLog.setEditable(false);
taLog.setLineWrap(true);
taLog.setFont(new Font("Arial", Font.PLAIN, 12));
scrollPane.setViewportView(taLog);
epInfo = new JEditorPane();
epInfo.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
epInfo.setFont(new Font("Tahoma", Font.PLAIN, 12));
epInfo.setContentType("text/html");
epInfo.setEditable(false);
epInfo.setBackground(null);
epInfo.setBorder(null);
epInfo.setBounds(10, 241, 375, 37);
setInfoText();
contentPane.add(epInfo);
Problem is whenever JTextArea changes its value button is not refreshed - it just dissapears - until I will drag mouse cursor over it. I suppose then some repaint() is launched.
I figured out I can add DocumentListener to JTextArea and there manually refresh button but it works until scroll bar appears in JScrollPane.
I can also use
scrollPane.getViewport().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e)
{}});
but it is invoked many times and all those refreshes are not neccesary.
Is there any reasonable (and efficient) way to check if JScrollPane changed?

Null layout is useful in this case because main window is fixed
No it is not useful.
Any time you code uses random numbers (ie to set the size/location) of components) the code is not easily maintainable.
Also I use WindowBuilder
Code generated by an IDE is not maintainable in another IDE.
Learn to use layout managers. The point of using layout managers is to avoid hard coding of numbers and to make the code maintainable in any environment.
Problem is whenever JTextArea changes its value button is not refreshed
contentPane.add(scrollPane);
...
contentPane.add(btnClean);
Swing is designed to display components in two dimension when added to the same container.
If you want components displayed in two dimension then you need to have a parent / child relationship:
- content pane
- text area
button
So the code should be something like:
textArea.setLayout( new FlowLayout(FlowLayout.RIGHT) );
//contentPane.add(btnClean);
textArea.add(btnClean);
Note: you can configure the FlowLayout to remove the spacing on the top and right.
The problem with this is that the button will cover any text that displayed in the text area.
So the better solution is to make the button external to the text area.

Related

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>";

JScrollPane acts funny inside of a JOptionsPane

I have tried to add a scroll view to a JOptionsPane, so that the information window can handle more text. It does add a scroll pane to the window. However, it acts funny on scrolling. The first visible text is shown clearly, but when you start scrolling, the text parts will overlap each other, until the text area is all black.
Do you have an explanation of how this can be and maybe a solution to the problem?
My code looks like this:
public void showInfoNoTranslation(String info) {
frame.requestFocusInWindow();
// create a JTextArea
JTextArea textArea = new JTextArea(info, 6, 25);
textArea.setEditable(false);
textArea.setBackground(new Color(255, 255, 255, 0));
textArea.setBorder(BorderFactory.createEmptyBorder());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
// if (textArea.getLineCount() > 5) {
JScrollPane scrollPane = new JScrollPane(textArea);
JOptionPane.showMessageDialog(_frame, scrollPane, "title", JOptionPane.INFORMATION_MESSAGE);
}
Call textArea.setOpaque(false); instead of setting it's background-color to fully transparent and it will work.
From the docs:
public void setOpaque(boolean isOpaque)
If true the component paints every pixel within its bounds. Otherwise, the component may not paint some or all of its pixels, allowing the underlying pixels to show through.
The default value of this property is false for JComponent. However, the default value for this property on most standard JComponent subclasses (such as JButton and JTree) is look-and-feel dependent.

JscrollPane doesn't enable ScrollBars whenever content gets to big

I have a JScrollPane processesScrollPane which has a JPanel processButtonPanel as component. Now in this component I add JButtons which come from an ArrayList I fill up while the programming is running.
I've set some settings of the JScrollPane, but the problem I'm having is that when there are more buttons in the JPanel then I can display, the JScrollPane isn't enabling its scrollbars.
Here some code snippets:
processesScrollPane = new JScrollPane();
processesScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
processesScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
processesScrollPane.setBounds(12, 42, 221, 380);
processPanel.add(processesScrollPane); //processPanel is the JPanel which holds the JScrollPane
processButtonPanel = new JPanel(); // here are the buttons added whenever they are made and placed in the buttonList
processesScrollPane.setViewportView(processButtonPanel);
processButtonPanel.setLayout(null);
processesScrollPane.setViewportView(processButtonPanel);
buttonList = new ArrayList<JButton>();
and the code where I'm making the buttons:
JButton b = new JButton("Process " + i);
b.setBounds(12, 5 + (30*i), 174, 25);
processButtonPanel.add(b);
processButtonPanel.repaint();
buttonList.add(b);
processesScrollPane.revalidate();
processesScrollPane.repaint();
(Yes I'm using no layout, but that's because I'm not going to scale the whole window etc)
Can anyone help me with the enabling of the scrollBars at the right time?

Swing: An automatic resizing Text above a button?

I am looking for a way to do the following:
Have a JDialog with a fixed width.
In it is a JTextArea (or whatever you suggest is a better component...) which receives a text of varying length (somewhere between 0 and 30 line)
Below that text is a button.
The dialog is automatically sized in height to make sure all the Text AND the button is being displayed.
The closest I have come to a solution is this, but the JTextArea does not seem to know how large it is after it did the automatic line breaks!
public PleaseResize(){
super();
Container cp = this.getContentPane();
cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));
JTextArea area = new JTextArea();
area.setColumns(20);
area.setLineWrap(true);
area.setEditable(false);
area.setWrapStyleWord(true);
area.setText("Once upon a midnight dreary, while I pondered, weak and weary, over many a quaint an curious volume of forgotten lore.");
cp.add(area);
cp.add(new JButton("Hallo"));
this.pack();
}
Scrolling the Text is unfortunately not an option.
I have asked this is a slightly different way before here: Resize Dialog properly after automatic LineWrap, but perhaps the JTextArea is the wrong component after all? Am I using the wrong LayoutManager? All of them seem unable to determine how large the dialog should be, though. Why does the JTextArea fail to communicate it's height after adding line-breaks to the text to the outside?
Here is the working code:
public PleaseResize() throws BadLocationException {
super();
Container cp = this.getContentPane();
cp.setLayout(new BorderLayout());
JTextArea area = new JTextArea();
area.setColumns(20);
area.setLineWrap(true);
area.setEditable(false);
area.setWrapStyleWord(true);
area.setText("Once upon a midnight dreary, while I pondered, weak and weary, over many a quaint an curious volume of forgotten lore.");
System.out.println(area.getLineCount());
JScrollPane pane = new JScrollPane(area);
cp.add(pane, BorderLayout.CENTER);
cp.add(new JButton("Hallo"), BorderLayout.SOUTH);
this.pack();
this.pack();
}
Packing twice still seems a bit weird to me, but it does solve the resizing problems :).
Try this aproach to resize JTextArea based in its model.
Rectangle modelToView = area.modelToView(area.getDocument().getLength());
if (modelToView != null) {
area.setSize(area.getWidth(), Math.max(area.getHeight(), modelToView.height + modelToView.y));
area.doLayout();
}

JScrollPane is not adding to my JList.

Im trying to add a Scroll bar to my JList. I want only 4 headings to be available on my JList at a time. When I add a JList and run my program, the JList disappears from the screen. Can someone help me fix this problem? I am using Java Eclipse.
This is my code:
songList1 = new JList (ListData);
songList1.setVisibleRowCount(4);
songList1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
songList1.setBounds(300,100,100,200);
panel.add(new JScrollPane(songList1);
You can try one of the following:
set panel's layout or
set scroll panes bounding area by scrollPane.setBounds()
Just an oversight:
songList1 = new JList(ListData);
songList1.setVisibleRowCount(4);
songList1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane songList1ScrollPane = new JScrollPane(songList1)
//songList1ScrollPane.setBounds(300, 100, 100, 200);
songList1ScrollPane.setBounds(10, 10, 100, 200);
panel.setLayout(null); // Absolute positioning
panel.add(songList1ScrollPane);
...
add(panel); // Or so
Of course the panel should have an appropiate layout.

Categories