JFrame setIconImage() works on windows but not on Mac - java

I was wondering if anyone knows why the following code to set the IconImage from my JFrame only works on windows but not on MacOS.
public ClientGUI(String title) {
setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/icons/ww_icon.png")));
setContentPane(contentPane);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}

Take a look at the Taskbar class instead
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.Taskbar;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
Image image = ImageIO.read(getClass().getResource("/images/16x16.png"));
Taskbar taskbar = Taskbar.getTaskbar();
taskbar.setIconImage(image);
JFrame frame = new JFrame();
frame.setIconImage(image);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
setBorder(new EmptyBorder(64, 64, 64, 64));
add(new JLabel("Hello World"));
}
}
}
I'd also consider having a look at the Desktop class as well

Related

Are transparent JFrame backgrounds not possible in Windows 10?

I have a JPanel in an undecorated JFrame. I want to draw an image to the JPanel. When the image contains transparent pixels, I want these to be "see-through" so that you can see whatever is behind the window.
All my research has told me that I should make
myJFrame.setUndecorated(true);
myJFrame.setBackground(new Color(0,0,0,0));
myJPanel.setOpaque(false);
, but as soon as my JFrame's background color's alpha is anything else than 255, my JPanel is not being drawn to anymore.
So, based on my limited testing, it seems to work fine on Windows 10
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
public TestPane() throws IOException {
img = ImageIO.read(...);
setOpaque(false);
setBorder(new LineBorder(Color.RED));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
g2d.drawImage(img, x, y, this);
g2d.dispose();
}
}
}
And just to be sure, I did a test using a JLabel...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() throws IOException {
BufferedImage img = ImageIO.read(...);
setOpaque(false);
setBorder(new LineBorder(Color.RED));
setLayout(new BorderLayout());
add(new JLabel(new ImageIcon(img)));
}
}
}
This would suggest that the issue is somewhere in the code you're not showing us. Consider providing a runnable example which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses

Resizing BasicArrowButton

I'm trying to get a BasicArrowButton component to resize and can't get it to work for the life of me. The following code is a much simpler version of the problem, but still demonstrates what I'm trying to do. The button is in a JPanel with the panel's layout set to FlowLayout. It needs to resize while still remaining in the panel with the same layout. Thanks in advance, and sorry for bad formatting:
Main class:
package PackageMain;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Main {
public static JFrame frame = new JFrame("Window");
public static PanelOne p1;
public static PanelTwo p2;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 800, 600);
p1 = new PanelOne();
frame.setVisible(true);
} catch(Exception e){
}
}
});
}
}
Second Class:
package PackageMain;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicArrowButton;
public class PanelOne{
public PanelOne(){
FlowLayout fl = new FlowLayout();
BasicArrowButton b1 = new BasicArrowButton(BasicArrowButton.WEST);
JPanel p1 = new JPanel();
p1.add(b1);
p1.setLayout(fl);
b1.setPreferredSize(new Dimension(100, 100)); //DOESN'T WORK!
Main.frame.add(p1);
}
}
The problem is that the class BasicArrowButton overrides the method getPreferredSize(). So you either need to use layout, which does not honor this method, or provide your own implementation for this method.
First proposal:
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicArrowButton;
public class BasicArrowButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frm = new JFrame("Test arrow button");
JPanel p = new JPanel(new GridLayout(1, 1));
p.setPreferredSize(new Dimension(100, 100));
p.add(new BasicArrowButton(BasicArrowButton.WEST));
frm.add(p);
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
});
}
}
Second proposal:
package org.swingsamples.label;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicArrowButton;
public class BasicArrowButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frm = new JFrame("Test arrow button");
JPanel p = new JPanel(new FlowLayout());
BasicArrowButton btn = new BasicArrowButton(BasicArrowButton.WEST) {
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
p.add(btn);
frm.add(p);
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
});
}
}

How I can define a JRadioButton with large size?

I'm learning java. for my GUI program need to large radio buttons (larger than the standard). What can I do?
I use Java Netbeans IDE - the latest version.
You can supply you're own images for radio button, see JRadioButton#setIcon, JRadioButton#setSelectedIcon and How to Use Buttons, Check Boxes, and Radio Buttons for more details...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class RadioButtonTest {
public static void main(String[] args) {
new RadioButtonTest();
}
public RadioButtonTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
try {
BufferedImage checked = ImageIO.read(getClass().getResource("/Checked.png"));
Image unchecked = ImageIO.read(getClass().getResource("/Unchecked.png")).getScaledInstance(300, 300, Image.SCALE_SMOOTH);
JRadioButton btn = new JRadioButton("I'm not fat, I'm just big boned");
btn.setSelectedIcon(new ImageIcon(checked));
btn.setIcon(new ImageIcon(unchecked));
btn.setHorizontalTextPosition(JRadioButton.CENTER);
btn.setVerticalTextPosition(JRadioButton.BOTTOM);
setLayout(new GridBagLayout());
add(btn);
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}

How to set JTextField border size in java

I want to set the Border height,width of JTextField and want to put it on the center of the JFrame in java.
I tried those ideas but those ideas does not work.
setSize(),SetPrefferedSize(),SetMaximumSize();
Need Help. Thanks in advance.
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class P{
public static void main(String [] args){
JFrame frame = new JFrame();
JTextField field = new JTextField();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(BorderLayout.NORTH,field);
frame.setSize(350,300);
frame.setVisible(true);
}
}
You could try using a LineBorder on the JTextField and place it within a container using GridBagLayout
For example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class BorderText {
public static void main(String[] args) {
new BorderText();
}
public BorderText() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField field = new JTextField(10);
field.setBorder(new LineBorder(Color.RED, 10));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(field);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Take a look at How to Use Borders and A Visual Guide to Layout Managers for more details

JFrame not repainting

I've been trying for at least an hour on refreshing my simple Jframe. I have tried repaint() revalidate; and just about anything else on the internet.
here is my entire class:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
public final class BRUTEFORCE {
static int Passwords = 0;
static JFrame frame;
public static void main(String[] args) {
//Create and set up the window.
frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel textLabel = new JLabel("Passwords tried: " + Passwords,SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(300, 100));
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
//Display the window.
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
Passwords++;
new Thread("Refresh") {
public void run () {
while(true){
frame.invalidate();
frame.validate();
frame.repaint();
}
}
}.start();
new Thread("Test") {
public void run () {
while(true) Passwords++;
}
}.start();
}
}
What am I doing wrong?
Two things are going wrong. You're first thread is constantly feeling the Event Queue with update requests, probably faster then the Event Queue can process them which may eventually flood it, degrading the performance of the system.
Secondly, you never actually change the text of the textLabel
For example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public class BruteForce {
static transient int Passwords = 0;
static JFrame frame;
public static void main(String[] args) {
//Create and set up the window.
frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JLabel textLabel = new JLabel("Passwords tried: " + Passwords, SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(300, 100));
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
//Display the window.
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
Passwords++;
new Thread("Test") {
public void run() {
while (true) {
try {
Passwords++;
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
textLabel.setText("Passwords tried: " + Passwords);
}
});
Thread.sleep(5);
} catch (InterruptedException ex) {
Logger.getLogger(BruteForce.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}.start();
}
}
Now, instead of a Thread, you might consider using a SwingWorker instead...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class BruteForce {
static transient int Passwords = 0;
static JFrame frame;
public static void main(String[] args) {
//Create and set up the window.
frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JLabel textLabel = new JLabel("Passwords tried: " + Passwords, SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(300, 100));
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
//Display the window.
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
SwingWorker worker = new SwingWorker<Integer, Integer>() {
#Override
protected void process(List<Integer> chunks) {
// Only care about the last one..
int value = chunks.get(chunks.size() - 1);
textLabel.setText("Passwords tried: " + value);
}
#Override
protected Integer doInBackground() throws Exception {
while (true) {
// Perform long running process...
// Forced delay to simulate long running process
Thread.sleep(5);
Passwords++;
publish(Passwords);
}
}
};
worker.execute();
}
}

Categories