I'm creating a very simple Swing GUI consisting of a scrollable text area. However, I'm having some problems with the responsiveness of the UI. Here is the class I am using to try some different configurations:
public class ComponentSample {
public void createWindow() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
TextArea textArea = new TextArea(getFillerText(), 40, 120);
setViews(frame, textArea);
frame.pack();
frame.setVisible(true);
}
private void setViews(JFrame frame, TextArea textArea) {
...
}
private String getFillerText() {
String threeLines = "Why isn't scrolling smooth? \nSteve Jobs would not approve\n\n";
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 100; i++) {
stringBuilder.append(threeLines);
}
return stringBuilder.toString();
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(
() -> new ComponentSample().createWindow()
);
}
}
Here I have tried several different method bodies for the setViews() method with the following results:
Adding textArea in a JPanel
JPanel panel = new JPanel();
panel.add(textArea);
frame.add(panel);
Scrolls by 1 or 2 rows instead of by pixel (not smooth). Also flashes white when scrolling quickly (repainting issue?).
Adding textArea in a Viewport
JViewport viewport = new JViewport();
viewport.setView(textArea);
frame.add(viewport);
Same results as JPanel.
Adding textArea directly
frame.add(textArea);
Same results as JPanel.
Adding textArea in a ScrollPane
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
frame.add(scrollPane);
Doesn't seem to handle scrolling properly - it doesn't respond to the scrollwheel (only clicking the scrollbar). Scrolls by ~0.5 row instead of by pixel.
Also, in each of the above cases, when the scrollbar is dragged with the mouse it prints the following (error? IDEA shows it in red) to the stdout:
2016-03-17 09:45:33.413 java[40977:2845515] inOptions: {
JavaCUIThumbStartKey = 0;
"is.flipped" = 0;
kCUIOrientationKey = kCUIOrientVertical;
kCUIThumbProportionKey = "0.1328903585672379";
max = 0;
pressedpart = 0;
state = normal;
value = 0;
widget = scrollbar;
}
2016-03-17 09:45:33.413 java[40977:2845515] inOptions: {
JavaCUIThumbStartKey = 0;
"is.flipped" = 0;
kCUIOrientationKey = kCUIOrientVertical;
kCUIThumbProportionKey = "0.1328903585672379";
max = 0;
pressedpart = 0;
state = normal;
value = 0;
widget = scrollbar;
}
2016-03-17 09:45:33.414 java[40977:2845515] outHitPart = 0
If it matters, I'm on OS X.
My question is how can I make it scroll smoothly (pixel by pixel) without flashing white and without printing errors?