I recently decided to upgrade an old Swing application from Java 1.6 to 1.8. Unfortunately, when I build and launch the application under Java 8 the window appears and is empty. If I build and launch under Java 7 or 6 the content displays as expected. Here is a sample code that reproduced my problem:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SwingRenderingIssue {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setTitle("hello world");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.add(new JButton("hello again"));
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}
});
}
}
The Java 8 version I have is jdk-8u181-linux-x64.
Related
I'm trying to implement a "iconify on quit" behavior in my Java JFrame app, like most native macOS apps have, but I'm quite stumped.
I've tried doing
Window.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent Event) {
System.out.println("Closed on macOS, iconifiying");
Window.setExtendedState(Frame.ICONIFIED);
}
});
and closing the window on quit with (as well as adding a window listener that calls setVisible(false))
Window.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
The former didn't work because it looks like it's minimized and creates 2 separate icons. The latter didn't because I couldn't find a way to detect when the dock icon is clicked to unhide the window. I'd prefer this method if I could figure out how to do so. Does anybody know how to?
Oh, I forgot to really specify what the behavior I'm trying to mimic really was. When you press the quit button on macOS, the window is made invisible. When you click the app's icon in the dock the window should be made visible again.
You really should read the JavaDocs, that and little bit of Googling brought me around to this simple example...
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.desktop.AppReopenedEvent;
import java.awt.desktop.AppReopenedListener;
import java.awt.desktop.QuitStrategy;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
Desktop.getDesktop().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Desktop.getDesktop().addAppEventListener(new AppReopenedListener() {
#Override
public void appReopened(AppReopenedEvent e) {
frame.setVisible(true);
}
});
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
add(new JLabel("Now you see me"));
}
}
}
I have a Java Swing app with some javaFX features. I am using Java 8.
I have some troubles with "scale and layout settings", if the "size of text, apps and other items" is 100% everything works fine. But if the percentage is 150% (which is the recommended size for my pc) as soon as this instruction is run:
PlatformImpl.startup
It seems that the "internal layout" of my app changes to 100%.
Is there anyone with the same problem? Is there a way to set the scale percentage (and maybe a way to retrieve it beforehand)?
EDIT:
I am using the latest jre/jdk 8 available (1.8 update 311)
Here is a minimal reproducible example:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.sun.javafx.application.PlatformImpl;
import javafx.application.Platform;
public class JavaFXTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btn = new JButton();
btn.addActionListener(e ->
//This is the culprit
PlatformImpl.startup(() -> System.out.println("javaFX started"))
);
JPanel panel = new JPanel();
JLabel label = new JLabel("Some character for testing");
panel.add(btn);
panel.add(label);
frame.getContentPane().add(panel);
// Display the window.
frame.pack();
frame.setVisible(true);
}
}
I am trying to get an image to appear inside of my JFrame. However, this image only appears when I maximize the GUI window. My image is located inside my src folder. I was wondering if I am implementing JFrame incorrectly.
UPDATED CODE
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JLabel(new ImageIcon("logo.png")));
frame.pack();
frame.setVisible(true);
Simple example.
The image is placed within stof package. The example makes use of ImageIO to load the image. The reason for this is two fold.
If something goes wrong, an exception is raised, so you can diagnose it
ImageIO.read won't return until the image is fully loaded. This means that, unlike ImageIcon, you know the image is available for rendering once the call returns. Just remember, if the image is large and you do this from within the event dispatching thread, you will cause the UI to "stall"
Example
import java.awt.EventQueue;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
BufferedImage image = ImageIO.read(Test.class.getResource("/stof/Background.png"));
JFrame frame = new JFrame();
frame.add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
}
I have the following swing code :
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class JFrameDemo {
private JFrame jframe = new JFrame();
public JFrameDemo() {
jframe.setSize(new Dimension(800, 20));
jframe.setUndecorated(true);
jframe.getContentPane().add(new JLabel("xxxxxxxxxxx"));
jframe.setVisible(true);
jframe.setAlwaysOnTop(true);
jframe.setLocation(0, 0);
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
jframe.setMaximizedBounds(env.getMaximumWindowBounds());
jframe.toFront();
jframe.repaint();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JFrameDemo();
}
});
}
}
My jframe window is always on top and also in the top of the screen but when other window from os ,like a browser window, is maximized my jframe overlaps that window .
When any os windows are maximized to be maximized below my jframe window.
you can see:
WRONG Behavior
GOOD Behavior
Since I understood java has no support for that feature so I am asking now if exists any native library which should I load using the jni.
So the behavior that I am looking for can be made using the jna lib: Docking a java application jna on windows
I'm on Ubuntu 15.04 and I have written following program:
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TimeTable extends Frame {
private Frame frame;
public TimeTable(){
setupGUI();
}
private void setupGUI(){
frame = new Frame("TimeTable");
frame.setSize(400, 400);
frame.addWindowListener(new WindowAdapter(){
public void wndClose(WindowEvent wndEvent){
System.exit(0);
}
});
frame.setVisible(true);
}
public static void main(String[] args){
TimeTable timetable = new TimeTable();
}
}
It should be a little GUI (AWT) Test-Window.
I build it with:
>> javac TimeTable.java
And run it with:
>> java TimeTable
The ICON of the AWT APP is shown in my Launcher Sidebar, but the Window doesn't appears on my Desktop.
Why not?
You can install Java on Ubuntu without graphics libraries (headless?).
Install the standard Java including graphics libraries and it should work. Your code works fine on Windows inside IntelliJ.