Java 9 changed default title height of JFrame after resizing is disabled - java

My Swing application cannot get consistent appearance between Java 8 and Java 9. It doesn't use a layout manager, so that all components are given exact size, but I found that running with Java 9, title of JFrame gets a different height and the status bar is not fully rendered. Please refer to the attached screen dump; it seems it is a bug.
I also studied how to repeat it with a simple demo program and found that it is not related to a layout manager. It seems that problem occurs after resizing is disabled. Please try the attached demo source code.
I also tried the following parameters, but they don't help:
-Dsun.java2d.uiScale=1.0
-Dprism.allowhidpi=false
My system runs Windows 10 1709 / Java 9.0.4:
D:\JavaEnv\J2SE9.X64\bin>java -version
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
D:\JavaEnv\J2SE9.X64\bin>ver
Microsoft Windows [Version 10.0.16299.371]
Screen dump:
Sample program:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.UIManager;
public class FirstFrame extends JFrame
{
private static final long serialVersionUID = 1L;
public FirstFrame()
{
JToolBar toolbar = new JToolBar();
getContentPane().add(new JTextArea(), BorderLayout.CENTER);
JToolBar statusbar = new JToolBar();
statusbar.add(new JLabel("Status:"));
getContentPane().add(statusbar, BorderLayout.SOUTH);
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("File");
menubar.add(menu);
super.setJMenuBar(menubar);
super.setTitle("Default Frame");
// It seems that problem is here.
setSize(new Dimension(300, 300));
setResizable(false);
super.setLocation(100, 100);
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
super.setVisible(true);
}
public static void main(String[] args) throws Exception
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new FirstFrame();
}
}

The problem is confirmed as a bug by the Java bug system at:
JDK-8202015: JFrame.setResizable(false) gives different frame size & title height from Java 8
Let's wait for the bugfix.

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.

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.

Java Swing fullscreen with keyboard input on Mac OS X

I'm having some issues getting my Java JFrame to be fullscreen on all OS (Windows, Mac, Linux). It seems whatever solution I find it does run on one OS but not on others or has some other serious bugs. I wanted to use the setFullScreenWindow(window w) method to properly initiate a fullscreen because setExtendedState(...) won't work on Mac/Linux as the menubar and taskbar are still visible.
The setFullScreenWindow(...) method worked fine on all environments until Java 7 came along and now there seems to be an issue that as soon as you enter fullscreen mode the application no longer responds to key events on Mac OS X. The application works just fine on Windows.
Does anyone have a clue how I could possibly work around this issue?
Note:
The workaround described here (FullScreen Swing Components Fail to Receive Keyboard Input on Java 7 on Mac OS X Mountain Lion) does not work for Windows because it will result in the JFrame flickering and not opening properly.
The fullscreen approach described here is the same used below which does not work because of problems with the key input: (How to make a JFrame really fullscreen?)
Example Code:
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
public class FullScreenKeyTest extends JFrame {
public void createFrame() {
initKey();
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
this.setUndecorated(true);
this.setVisible(true);
gd.setFullScreenWindow(this);
}
private void initKey() {
Action keyAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("Escape key pressed");
setVisible(false);
System.exit(0);
}
};
this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "keyPress");
this.getRootPane().getActionMap().put("keyPress", keyAction);
}
public static void main(String[] args) {
FullScreenKeyTest testFrame = new FullScreenKeyTest();
testFrame.createFrame();
}
}
This is a bit flaky as I can get it to work and break it at the same time.
With your example code, I added
getContentPane().setFocusable(true);
getContentPane().requestFocus();
To the end of the createFrame method, and instead of registering the action against the root pane, I registered against the content pane
I found that keyboard inputs work if you use the native OS X Lion fullscreen API. See solution to the question Fullscreen feature for Java Apps on OSX Lion.

Moving JScrollPane horizontally results in blured text

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.

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