Moving JScrollPane horizontally results in blured text - java

I have a TextArea inside JScrollPane inside standard JPanel.
JPanel panelMain = new JPanel();
panelMain.setBorder(titledBorder1);
panelMain.setBounds(new Rectangle(2, 5, 970, 700));
panelMain.setLayout(null);
JTextArea fieldBody = new JTextArea();
JScrollPane fieldBodyScrollPane = new JScrollPane(fieldBody);
fieldBodyScrollPane.setBounds(70, 140, 790, 500);
panelMain.add(fieldBodyScrollPane);
When I type enough text in a single row the horizontal knob appears - so far good. But when I start moving the knob left and right, the text gets blured (see image). Interestingly, nothing weird happens when I move the textarea up and down.
I use Ubuntu 12.04 with Unity. This graphic artifact never appeared to me before. Any hints what could be the problem?

import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.border.*;
public class CaseForLayoutsNumber547 {
CaseForLayoutsNumber547() {
Border titledBorder1 = new TitledBorder("Case for Layouts #547");
// START: code snippet variant
JPanel panelMain = new JPanel(new GridLayout());
panelMain.setBorder(titledBorder1);
JTextArea fieldBody = new JTextArea(5,40);
JScrollPane fieldBodyScrollPane = new JScrollPane(fieldBody);
panelMain.add(fieldBodyScrollPane);
// END: code snippet variant
JOptionPane.showMessageDialog(null, panelMain);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new CaseForLayoutsNumber547();
}
};
SwingUtilities.invokeLater(r);
}
}
I do not see any scroll artifacts in this SSCCE. Do you?

Here's #Andrew's SSCCE displaying itself; it looks the same with either Ambience or Radiance.
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 12.04.1 LTS
Release: 12.04
Codename: precise
$ java -version
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.4) (6b24-1.11.4-1ubuntu0.12.04.1)
OpenJDK Client VM (build 20.0-b12, mixed mode, sharing)
Addendum: Looking closer at your screenshot, failing to honor the opacity property can cause such rendering artifact, and the default setting may vary among Look & Feel implementations.

This problem happens in OpenJDK (6 and 7, at least; and at least on Linux), and does not happen in Oracle Java 6 and 7 (on Linux).
The workaround suggested by mKorbel works for me:
scrollPane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
So I guess it's a bug in OpenJDK.

Related

JButton text changes on its own?

The following simple code:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class ButtonTextMain {
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
final JTextField field = new JTextField(20);
final JButton button = new JButton("Click to change text");
button.addActionListener(e -> button.setText(field.getText()));
final JPanel panel = new JPanel(new BorderLayout());
panel.add(field, BorderLayout.CENTER);
panel.add(button, BorderLayout.PAGE_END);
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
can always reproduce the same bug (at least for my setups, which are given below).
The program is supposed to change the button text, according to the text-field's text, when the button is clicked.
The problem is that the text of the button reverts/changes back to its previous value on its own unexpectedly.
The problem arises when I use the Tab to alternate/navigate between the button and the text-field. Here are the specific steps which always reproduce the same bug on my setups:
Run the program.
Resize the frame to be a bit bigger than it was.
Type some short text in the text-field.
Press Tab to navigate the focus to the button.
Press Spacebar to invoke the button.
Press Tab to navigate the focus back to the text-field.
Type any letter you like into the text-field.
Notes:
I know that step 2 is relevant, because if I ommit it then the bug does not reproduce.
After step 2 (and before 3), the mouse should not be needed any more. Leave it. The focus of the program should be in the text-field as it was when the program launched.
In step 3 I usually type something like abc but the error repoduces for any other input I tried.
In step 6 you can also use Shift+Tab to navigate back to the text-field.
On step 7, after typing the first letter, you will see that the button's text changes back to its initial/previous value.
My first tested setup:
Apache NetBeans IDE 8.2, which is a bit outdated.
java -version yields:
java version "1.8.0_321"
Java(TM) SE Runtime Environment (build 1.8.0_321-b07)
Java HotSpot(TM) Client VM (build 25.321-b07, mixed mode)
javac -version yields javac 1.8.0_161. There is a missmatch here with the runtime environment.
My second tested setup:
Apache NetBeans IDE 11.0.
java -version yields:
java version "12.0.2" 2019-07-16
Java(TM) SE Runtime Environment (build 12.0.2+10)
Java HotSpot(TM) 64-Bit Server VM (build 12.0.2+10, mixed mode, sharing)
javac -version yields javac 12.0.2.
The operating system is Windows 10 on both setups.
So the question is: did I do something wrong, and if so, what is it please? First of, can anybody else reproduce the bug I am getting on their setup?
Update:
I can also reproduce this behaviour on the system L&F too, by using:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
inside just before the JTextField creation (and catching exceptions, etc).
Based on the above comments I retested and now I am able to reproduce the problem. The issue occurs when you increase the vertical height of the text field (by some minimal amount).
I guess I tested before by only increasing the horizontal size of the text field.
I found a simple work around:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class ButtonTextMain {
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
final JTextField field = new JTextField(20);
final JButton button = new JButton("Click to change text");
button.addActionListener(e ->
{
button.setText(field.getText());
//button.getParent().revalidate();
button.getParent().repaint();
});
final JPanel panel = new JPanel(new BorderLayout());
panel.add(field, BorderLayout.CENTER);
panel.add(button, BorderLayout.PAGE_END);
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
This definitely seems like a bug to me.
Having said that, rarely would you want the vertical height of the text field to increase in size. So maybe you can find a layout manager that only affects the horizontal size and not the vertical height?
I don't have this problem.
I use VScode, java version 1.8.0.25.
I think problem is your compiler.

Java crashes when creating a JFrame

I am baffled at this issue. I just wanted to create a JFrame for testing, this is the only class:
import javax.swing.*;
public class TextPaneTest extends JFrame {
public TextPaneTest(){
setTitle("Test");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setSize(200, 200);
setVisible(true);
}
public static void main(String[] args){
new TextPaneTest();
}
}
I am using IntelliJ IDEA 2019.2.4 as my IDE.
The result is a small white JFrame opens up for 2 seconds and closes. You can't move or resize the window and the cursor remains in "wait" mode when you hover the frame.
This is my project structure:
And this is my run configuration:
There is no error message or exception. All the console shows is:
Process finished with exit code -1073740771 (0xC000041D)
I've already done a clean reinstall of both the JRE and JDK
This is my current java -version:
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
My OS is Windows 10 Home Single Language 1903
I don't know what else to add. I've been using Java for the past 5 years as a hobbyist and I've never came across an issue so fundamental as this.
Update
Tried instantiating TextPaneTest() using SwingUtilities.invokeLater()
Tried building the JAR and running from a command window
None has worked so far. Exactly the same behaviour.
Update 2
Fixed it by switching the 64 bit JRE for the 32 one. Is this a bug with the 64 one or could there be an underlying problem?
I cannot reproduce the issue on my macintosh, but I notice you are doing everything on the main thread. You shouldn't do that. Make sure all events happen on the Event Dispatch Thread. For example,
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TextPaneTest();
}
});
}

Why is my Java swing window not showing up?

so I'm starting to learn Java Swing, following a YouTube video.. installed Java 8 and NetBeans 8.0 in Linux Ubuntu 14.04. Made a new Java application, and wrote the following code:
package basicswing;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
public class BasicSwing extends JFrame {
JPanel p = new JPanel();
JButton b = new JButton("Hello");
public static void main(String[] args) {
new BasicSwing();
}
public BasicSwing() {
super("Basic Swing App");
setSize(400,300);
setResizable(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
p.add(b);
add(p);
setVisible(true);
}
}
When I clean, build, and then run the project, it shows that a Java project is running, but I don't see the Frame, it doesn't pop up.. I don't actually think it's a code issue, I've tried it with different code, and the frame still doesn't show. I can't figure out if it's a NetBeans issue or a Java issue.. or maybe something else?
It is an environment (NetBeans maybe?) issue. Try running from command line:
$ javac BasicSwing.java
$ java BasicSwing
The code is correct and displays the frame.

Look & Feel troubles on Ubuntu

I'm writing an app that requires some widgets to use different look & feels. The rest of the app uses the system look & feel.
My approach to this was while initializing the app to swap the LF for the desired one, create the component and then reset the LF. This worked fine on Windows operating systems, but while testing it on Ubuntu it failed to set the LF for the component in a bizarre way.
On Ubuntu, UIManager.getSystemLookAndFeelClassName() reports that that the LF is a javax.swing.plaf.metal.MetalLookAndFeel. This is the first bit of trouble - I'd expect it to return com.sun.java.swing.plaf.gtk.GTKLookAndFeel. The strange part is that my approach works when the program is using the Metal LF, but fails when using the GTK LF, where it sets the entire frame and all components within it to the GTK LF.
The following SSCCE demonstrates the issue:
import javax.swing.*;
import java.awt.*;
import static javax.swing.UIManager.*;
public class LaFTest {
public static void main(String[] argv) throws ReflectiveOperationException, UnsupportedLookAndFeelException {
String[] keys = {
"java.specification.version",
"java.version",
"java.vm.version",
"java.specification.vendor",
};
for (String key : keys) {
System.out.printf("%-40s%s\n", key, System.getProperty(key));
}
System.out.println(UIManager.getSystemLookAndFeelClassName());
// Swap for "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"
setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JFrame frame = new JFrame("LaF Test");
Container content = frame.getContentPane();
content.setLayout(new GridLayout(2, 0));
JButton button = new JButton("System");
content.add(button);
LookAndFeel previous = getLookAndFeel();
for (LookAndFeelInfo feel : getInstalledLookAndFeels()) {
if (feel.getName().equals("Nimbus")) {
setLookAndFeel(feel.getClassName());
}
}
JButton second = new JButton("Nimbus");
content.add(second);
setLookAndFeel(previous);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Note, however, that I am unsure regarding the reproducibility of this issue. As quick Google shows no similar issues, it may be something specific to my machine. Regardless, it has persisted when updating from Ubuntu 12 to 13, and 13 to 14. From this I assume it's an issue with Swing and not the underlying system.
The output of the above program is, on my machine,
java.specification.version 1.7
java.version 1.7.0_51
java.vm.version 24.51-b03
java.specification.vendor Oracle Corporation
javax.swing.plaf.metal.MetalLookAndFeel
Using the Metal feel, the resulting window is
Swapping for the GTK feel,
I've been playing around with this for a while now, with no results. Is there something I'm missing? Can anyone reproduce this, and if so is it a bug in the Java distribution or my code? Is there a better way to achieve my goal?
I would have loved to debug this in depth, but a nearing deadline forced me to install the Oracle Java package, which fixed the issue. A disappointing answer, but it did fix the issue permanently.

Cannot mix lightweight and heavyweight components in an undecorated JFrame

I am attempting to mix heavyweight and lightweight components according to these guidelines.
I am expecting the following code to paint the entire window green. Instead, it renders half the screen red:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
public class Testcase extends Canvas
{
private static final long serialVersionUID = 0L;
public static void main(String[] arg)
{
final boolean enableWorkaround = false;
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JLayeredPane layers = new JLayeredPane();
frame.getContentPane().add(layers);
JPanel green = new JPanel();
green.setBackground(Color.GREEN);
green.setBounds(0, 0, 800, 600);
layers.add(green, Integer.valueOf(1));
Canvas red = new Canvas();
red.setBackground(Color.RED);
red.setBounds(0, 0, 400, 600);
layers.add(red, Integer.valueOf(0));
frame.setSize(800, 600);
if (!enableWorkaround)
frame.setUndecorated(true);
frame.setVisible(true);
}
});
}
}
Reproduced on:
java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) Client VM (build 19.0-b09, mixed mode, sharing)
and
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b124)
Java HotSpot(TM) Client VM (build 20.0-b05, mixed mode, sharing)
Does my code contain any bugs or is this a legitimate JDK bug?
Your code appears to be fine, since it works as you'd think if you used a JPanel instead of a Canvas for red .This appears to be a bug in mixing heavyweight and lightweight components.
As mentioned in the selected answer for this question on overlapping components, it seems that it's still a bad idea to mix heavyweight and lightweight components if it involves overlapping a lightweight component over a heavyweight component.
However, overlapping a heavyweight over a lightweight component does seem to work, so if you change green into the Canvas and red into the JPanel, it will work. It will also work if both are JPanels or both are Canvases.
That said, unless you really need to, it's generally better to avoid mixing lightweight and heavyweight components.
Hope that helps.
According to Oracle, this is a known limitation that will be fixed in the future: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7012806

Categories

Resources