Create a Jdialog that has an icon just like joptionpane - java

I have a extended JDialog for a custom dialog because it's a bit complicated and I can't create it with JOptionPane but my issue is I still want to add to the JDialog the same icons that JOptionPane has to keep my dialogs similar in the entire app. These are the Icons provided by java in JOptionPane, but when I create a JDialog it doesn't have an Icon, how can I add one just like JOptionPane without changing into a JOptionPane.

On MacOS, JOptionPane, left to right, top to bottom, Error; Information; Warning; Question
Loaded from UIManager
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(2, 2));
frame.add(new JLabel(UIManager.getLookAndFeel().getDefaults().getIcon("OptionPane.errorIcon")));
frame.add(new JLabel(UIManager.getLookAndFeel().getDefaults().getIcon("OptionPane.informationIcon")));
frame.add(new JLabel(UIManager.getLookAndFeel().getDefaults().getIcon("OptionPane.warningIcon")));
frame.add(new JLabel(UIManager.getLookAndFeel().getDefaults().getIcon("OptionPane.questionIcon")));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JOptionPane.showMessageDialog(frame, "Test", "Test", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(frame, "Test", "Test", JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(frame, "Test", "Test", JOptionPane.WARNING_MESSAGE);
JOptionPane.showMessageDialog(frame, "Test", "Test", JOptionPane.QUESTION_MESSAGE);
}
});
}
}

Related

JPopupMenu appears but seems to not react

I've problems to get a JPopupMenu working correctly.
What I expect
The menu should pop up once I do a right click with my mouse. Then I can select an item from the menu and do whatever I want..
What I actually get
The menu appears once I do a right click but after that I can not select a menu item or at least I am missing the well known mouse hover highlight effect (I would expect that the item I am currently hovering is highlighted, like it is the case in the normal menu).
The see problem here (no highlight on hover):
Here is my example code:
package com.mycompany.mavenproject2;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class PopupMenuTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel pane = new JPanel();
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("A"));
popup.add(new JMenuItem("B"));
pane.setSize(300,300);
pane.add(popup);
pane.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e)) {
popup.setLocation(e.getXOnScreen(), e.getYOnScreen());
popup.setVisible(true);
}
}
});
frame.setTitle("Test");
frame.add(pane);
frame.setPreferredSize(new Dimension(300,300));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Edit
Compare to a "normal" menu with working hovering:
Edit #2
Please see the current (unexpected) behaviour:
You need to use the JPopupMenu show method, rather than the setVisible method.
Here's the code I tested with. I'm running Windows 10 and using the Java JDK 13.0.2 with Java 8 compliance. I get the highlight on the mouse over.
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class JPopupMenuTest implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new JPopupMenuTest());
}
#Override
public void run() {
JFrame frame = new JFrame();
JPanel pane = new JPanel();
pane.setPreferredSize(new Dimension(300, 300));
pane.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("A"));
popup.add(new JMenuItem("B"));
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
});
frame.setTitle("JPopupMenu Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

Java setBounds() method (JFrame)

Hi Im using the setBounds method to open a window whith a certain size. But the size that I pass in the argument is the size of the window including the bars of the frame. How can I set the dimensions only for the content?
Set the size of the content, then call pack() on the JFrame.
Edit: Because Guillaume Polet will not stop griefing me, here is a complete working example. Notice how you don't need to (mis)use inheritance at all, and it gets the job done in much fewer lines:
import java.awt.Dimension;
import javax.swing.JFrame;
public class Main {
public static void main(String... args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setPreferredSize(new Dimension(500, 500));
frame.pack();
frame.setVisible(true);
}
}
There are 2 ways to fix this:
Take into account the border of the frame when setting the bounds of the frame
Override getPreferredSize() of the content pane of the JFrame and then call pack() on the frame.
Here is a demo of the two techniques:
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
protected void initUI() {
JFrame frame = new JFrame("Insets technique");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Insets i = frame.getInsets();
System.out.println(i);
Rectangle bounds = new Rectangle(50, 100, 400, 500);
bounds.width += i.right + i.left;
bounds.height += i.bottom + i.top;
frame.setBounds(bounds);
}
protected void initUI2() {
JFrame frame = new JFrame("Preferred size technique");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 500);
}
});
frame.pack();
frame.setLocation(50, 100);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Test test = new Test();
test.initUI();
test.initUI2();
}
});
}
}

Mouse clicks ignored on modal JDialog

I'm having trouble understanding the behaviour of a modal JDialog.
When the dialog is set to visible all works fine until the user clicks back on the parent JFrame that was used to launch it. Although the dialog remains on top as expected, all subsequent mouse clicks back on the JDialog are ignored. The form items in the JDialog can still be filled in, but only if you navigate using tab. Is this normal or am I missing something obvious?
Below is a simple example that illustrates the behaviour:
import java.awt.BorderLayout;
import java.awt.Dialog.ModalityType;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class TestApp {
private JFrame frame;
public TestApp() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnRun = new JButton("run");
btnRun.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
JDialog dialog = getChildDialog();
dialog.setModalityType(ModalityType.APPLICATION_MODAL);
dialog.setVisible(true);
}
});
frame.getContentPane().add(btnRun, BorderLayout.CENTER);
}
public JDialog getChildDialog() {
JDialog dialog = new JDialog();
dialog.setModalityType(ModalityType.APPLICATION_MODAL);
dialog.setBounds(100, 100, 450, 300);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JTextField(), BorderLayout.CENTER);
panel.add(new JTextField(), BorderLayout.NORTH);
panel.add(new JTextField(), BorderLayout.SOUTH);
panel.add(new JLabel("Blah"), BorderLayout.EAST);
panel.add(new JLabel("Blah"), BorderLayout.WEST);
dialog.getContentPane().setLayout(new BorderLayout());
dialog.getContentPane().add(panel, BorderLayout.CENTER);
return dialog;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestApp window = new TestApp();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
Thank you for the feedback. I think this must be a bug in the JVM I'm using (OpenJDK 2.4.7 7u55-2.4.7-1ubuntu1).
I've just run the same code on a Windows Java 7 JVM and don't get the same behaviour. I will submit a bug report.

How to combine a JLabel and JFrame?

So as of now when I run the program two different panels open up. One is a JPanel and one is a JFrame. I was wondering how to either combine the two or just take the JLabel on the JPanel and put it on the JFrame I already have?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class MainQuestions {
public static void main (String args[]){
JFrame frame=new JFrame();
setLayout(new BorderLayout());
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JLabel bottomRtLabel = new JLabel("BOTTOM RIGHT LABEL");
labelPanel.add(bottomRtLabel);
frame.add(labelPanel,BorderLayout.SOUTH);
frame.setVisible(true);
Object ARRAY[]={"French","English","Portugese","Spanish"};
String answer=(String)JOptionPane.showInputDialog(frame, "What language predominately spoken in Latin American countries?","World Geography Review", JOptionPane.PLAIN_MESSAGE, null, ARRAY, null);
if (answer==null)
{
//System.exit(0);
}
else if (answer.equals("Spanish"))
{
JOptionPane.showMessageDialog(null, "Correct!", "World Geography Review", JOptionPane.PLAIN_MESSAGE,null);
//System.exit(0);
}
else
{
JOptionPane.showMessageDialog(null, "Sorry, wrong answer.", "World Geography Review", JOptionPane.PLAIN_MESSAGE,null);
//System.exit(0);
}
}
private static void setLayout(BorderLayout borderLayout) {
// TODO Auto-generated method stub
}
}
I find many errors in your code. For starts:
JFrame frame=new JFrame();
setLayout(new BorderLayout());
Should be:
JFrame frame=new JFrame();
frame.setLayout(new BorderLayout());
Also, you might want to move all your code to a Constructor. So your main may look like this:
public static void main (String args[]){
new MainQuestions();
}
Then inside the constructor, move all your code:
public MainQuestions(){
JFrame frame=new JFrame();
frame.setLayout(new BorderLayout());
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); // Read up on GridBagLayout
JLabel bottomRtLabel = new JLabel("BOTTOM RIGHT LABEL");
labelPanel.add(bottomRtLabel);
frame.add(labelPanel,BorderLayout.SOUTH);
frame.setVisible(true);
String ARRAY[]={"French","English","Portugese","Spanish"}; // Notice how I changed the type to String
String answer=(String)JOptionPane.showInputDialog(frame, "What language predominately spoken in Latin American countries?","World Geography Review", JOptionPane.PLAIN_MESSAGE, null, ARRAY, null);
if (answer==null)
{
//code
}
else if (answer.equals("Spanish"))
{
JOptionPane.showMessageDialog(null, "Correct!", "World Geography Review", JOptionPane.PLAIN_MESSAGE,null);
}
else
{
JOptionPane.showMessageDialog(null, "Sorry, wrong answer.", "World Geography Review", JOptionPane.PLAIN_MESSAGE,null);
}
System.exit(0);
}
}
I haven't run this edited code yet. Try it out by typing it yourself and debugging.
You may extend JPanel. Something like this:
public class MainQuestions {
public static void main (String args[]){
JFrame frame=new JFrame();
YourClass labelPanel = new YourClass();
frame.setLayout(new BorderLayout());
frame.add(labelPanel,BorderLayout.SOUTH);
setVisible(true);
}
class YourClass extends JPanel {
YourClass(){
//add label there
}
}

Swing: how to open and attach a new dialog into an existing frame?

I have got a frame in which sometimes a dialog is opened. I would like this dialog to be attached to the existing frame, so for example when I drag that frame the opened dialog follows it. I have heard that this might be possible to achieve using GlassPane but I need some hints. Right now, when I open a new dialog and set its location relative to frame it looks like this:
I would like the "testDialog" to appear next to the frame attached to its upper-right corner.
When I drag the "test" frame, the "testDialog" follows it.
Here is a working example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Example {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
showGUI();
}
});
}
public static void showGUI() {
final JFrame frame=new JFrame("test");
JButton open=new JButton("Open new dialog");
open.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("test");
JDialog dialog=new JDialog((Frame)null,"testdialog");
dialog.setPreferredSize(new Dimension(200,300));
dialog.getContentPane().add(new JLabel("testlabel"));
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
});
frame.setLayout(new FlowLayout());
frame.getContentPane().add(open);
frame.getContentPane().add(new JLabel("test"));
frame.setLocationRelativeTo(null);
frame.setPreferredSize(new Dimension(400, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}

Categories