Reputation: 988
I have made a class RefreshablePanel
that extends JPanel
public class RefreshablePanel extends JPanel {
static String description="";
static int x=10;
static int y=11;
protected void paintComponent(Graphics g){
super.paintComponent(g);
for (String line : description.split("\n"))
g.drawString(line, x, y += g.getFontMetrics().getHeight());
}
void updateDescription(String dataToAppend){
description = description.concat("\n").concat(dataToAppend);
System.out.println("The description is "+description);
}
}
and then I am adding it into my GUI_class like this
JScrollPane scrollPane_2 = new JScrollPane();
scrollPane_2.setBounds(32, 603, 889, 90);
frmToolToMigrate.getContentPane().add(scrollPane_2);
descriptionPanel = new RefreshablePanel();
scrollPane_2.setViewportView(descriptionPanel);
descriptionPanel.setBackground(Color.WHITE);
descriptionPanel.setLayout(null);
I have added the scrollbar in the class where I am making an instance of RefreshablePanel but scrollbar is not appearing. I have tried adding
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 1010);
}
to refreshable Panel but then the string is disappearing like this
and nothing is appearing when I scroll down
Upvotes: 0
Views: 229
Reputation: 347334
You're using null
layouts, so nothing is going to work the way it should. Swing is designed at the core to utilise layout managers.
You're RefreshablePanel
has no discernible size, meaning that when you add to the scroll pane, the scroll pane is likely to simply think it's size should 0x0
. RefreshablePanel
needs to provide some kind of size hint back to the scrollpane, preferably via the getPreferredSize
method
You could use a JLabel
(with text wrapped in html) or a non-editable JTextArea
to achieve the same results
Updated
Take a quick check of your code. You are declaring the x
and y
values as static
and you are incrementing the y
value in your paintComponent
method
static int x=10;
static int y=11;
protected void paintComponent(Graphics g){
super.paintComponent(g);
for (String line : description.split("\n"))
g.drawString(line, x, y += g.getFontMetrics().getHeight());
}
This means two things.
RefreshablePanel
they will ALL share the same x
/y
values AND update themy
is constantly being update to a new position, so if the panel is painted twice, on the second paint, the y
position will start from the position it was last at when the first call exited.Remember, you don't control the paint process. A paint cycle may be executed at any time that the system decides it needs to...
Make the x
/y
values local variables to the paintComponent
method...
Updated
The scroll pane will try and match the preferred size of the component if the available space allows for it. This may mean that the scroll bars may not appear until you resize the window...but you're using a null
layout so that won't work for you...
To affect the size of the scroll pane, you can use the Scrollable
interface instead...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Scrollable01 {
public static void main(String[] args) {
new Scrollable01();
}
public Scrollable01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
RefreshablePanel pane = new RefreshablePanel();
pane.updateDescription("1. You're using null layouts, so nothing is going to work the way it should. Swing is designed at the core to utilise layout managers.");
pane.updateDescription("2. You're RefreshablePanel has no discernible size, meaning that when you add to the scroll pane, the scroll pane is likely to simply think it's size should 0x0. RefreshablePanel needs to provide some kind of size hint back to the scrollpane, preferably via the getPreferredSize method");
pane.updateDescription("3. You could use a JLabel (with text wrapped in html) or a non-editable JTextArea to achieve the same results");
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(pane));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class RefreshablePanel extends JPanel implements Scrollable {
public String description = "";
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 1010);
}
@Override
protected void paintComponent(Graphics g) {
int x = 10;
int y = 11;
super.paintComponent(g);
for (String line : description.split("\n")) {
g.drawString(line, x, y += g.getFontMetrics().getHeight());
}
}
void updateDescription(String dataToAppend) {
description = description.concat("\n").concat(dataToAppend);
System.out.println("The description is " + description);
repaint();
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(400, 400);
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}
Upvotes: 3