How to use setOpaque(true/false) in an if statement - java

My JLabel won't change to a blue background. The JLabel is already set to the blue background but it is not opaque until you press the button. Why is it still not opaque?
Does setOpaque work for if statements?
import java.awt.Color;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.*;
public class TestOpaque {
public static void main (String args[])
{
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Label with blue background");
label.setBackground(Color.BLUE);
label.setOpaque(false);
frame.add(label, BorderLayout.WEST);
JButton button = new JButton("Button");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (label.isOpaque() == false) {
label.setOpaque(true);
label.revalidate();
}
}
});
frame.add(button, BorderLayout.EAST);
frame.pack();
frame.setVisible(true);
}
}

The if statement works fine, although better to use if (!label.isOpaque()) {
You need to redraw the GUI component via repaint() for the background to show:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!label.isOpaque()) {
label.setOpaque(true);
label.revalidate();
label.repaint();
}
}
});

Related

How do I get focus for a keypress in a CardLayout?

I had a CardLayout example working correctly with a button, then tried to convert it to work with keypress. I think the problem is that I don't have focus, but I can't set the focus to frame or panel successfully. Thanks!
I tried requestFocusInWindow from the frame and from the first panel shown, and that didn't help. I asked frame.getFocusOwner() and it returned null.
I thought that CardLayout would give the focus to the top element automatically, but while that worked when I had a button, it is not working now.
public class MyCardLayoutExample3 {
public static void main(String[] args){
MyCardLayoutExample3 game = new MyCardLayoutExample3();
game.display();
}
void display() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(300, 200);
CardLayout cardLayout = new CardLayout();
frame.getContentPane().setLayout(cardLayout);
MyGamePanel3 mgp3 = new MyGamePanel3("minigame A", Color.red);
frame.getContentPane().add(mgp3);
frame.getContentPane().add(new MyGamePanel3("minigame B", Color.green));
frame.getContentPane().add(new MyGamePanel3("minigame C", Color.blue));
frame.setVisible(true);
System.out.println("owner: " + frame.getFocusOwner()); //this prints null
}
}
class MyGamePanel3 extends JPanel implements KeyListener{
MyGamePanel3(String text, Color bg){
JLabel textLabel = new JLabel(text);
this.setBackground(bg);
this.add(textLabel);
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed worked");
}
#Override
public void keyReleased(KeyEvent e) {}
}
Changing to key bindings made the example work easily, thanks Abra. I never got the keyListener to work, despite trying the links above and many other links.
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
class MyGamePanel extends JPanel{
MyGamePanel(ActionListener alNext, String text, Color bg){
JButton buttonNext = new JButton("next");
buttonNext.addActionListener(alNext);
JLabel textLabel = new JLabel(text);
this.setBackground(bg);
this.add(textLabel);
this.add(buttonNext);
}
}
public class MyCardLayoutKeyBindingExample {
public static void main(String[] args){
MyCardLayoutKeyBindingExample game = new MyCardLayoutKeyBindingExample();
game.display();
}
void display() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(300, 200);
CardLayout cardLayout = new CardLayout();
//frame.getContentPane().setLayout(cardLayout);
JPanel mainPanel = new JPanel(cardLayout);
frame.add(mainPanel);
ActionListener al1 = e -> cardLayout.next(mainPanel);
mainPanel.add(new MyGamePanel(al1, "minigame A", Color.red));
mainPanel.add(new MyGamePanel(al1, "minigame B", Color.green));
mainPanel.add(new MyGamePanel(al1, "minigame C", Color.blue));
mainPanel.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "space");
Action kp = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("key pressed");
}
};
mainPanel.getActionMap().put("space", kp);
frame.setVisible(true);
}
}

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.

JLabel not updating

so thanks for looking at my question,Well anyways im trying to make a cookie clicker clone (if you could call it that) where you click the button and the JPanel updates, unfortunately the JPanel doesn't update and I just cant find an answer anywhere else, Any help is valuable help, thank you! Here is my code:
public int numCookies;
public main(){
//JButton
JButton click = new JButton("Click");
click.setLayout(null);
click.setLocation(50, 50);
click.setSize(80, 50);
click.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
numCookies = numCookies + 1;
}
});
//JLabel
JLabel cookies = new JLabel();
cookies.setLayout(null);
cookies.setText("Cookies:" + numCookies);
cookies.setLocation(480/2,10);
cookies.setSize(200, 50);
//JPanel
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setLocation(10, 0);
panel.setSize(260, 30);
panel.add(click);
panel.add(cookies);
//JFrame
JFrame frame = new JFrame("Cookie clicker!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 480);
frame.setLocationRelativeTo(null);
pack();
frame.setVisible(true);
frame.add(panel);
}
public static void main(String args[]){
new main();
}
Three things...
One...
Use of null layouts. Don't be surprised when things go wrong. When using JLabel or JButton, unless you intend to actually add something to them, you don't need to touch there layout managers.
Make use of approriate layout managers
Two...
Calling setVisible on your frame before you've finished filling it out...
JFrame frame = new JFrame("Cookie clicker!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 480);
frame.setLocationRelativeTo(null);
// No idea what you expect this to be doing...
pack();
//frame.setVisible(true);
frame.add(panel);
// This belongs here...and you shouldn't pack a window until
// it's ready to be made visible...
frame.setVisible(true);
Three...
You seem to expect that the lable will magically now that the value numCookies has changed...
click.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
numCookies = numCookies + 1;
// ??????
}
You need to reassign the value to the label in order for the label to be updated...
For example...
public main(){
//JLabel
// Make the lable final...so we can access from witin
// the listener...
final JLabel cookies = new JLabel();
cookies.setText("Cookies:" + numCookies);
//JButton
JButton click = new JButton("Click");
click.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
numCookies = numCookies + 1;
cookies.setText("Cookies:" + numCookies);
}
});
Bonus
Make sure you read through and understand Initial Threads
...And just because null layouts annoy me so much...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public int numCookies;
public Main() {
final JLabel cookies = new JLabel();
cookies.setText("Cookies:" + numCookies);
JButton click = new JButton("Click");
click.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
cookies.setText("Cookies:" + (++numCookies));
}
});
//JFrame
JFrame frame = new JFrame("Cookie clicker!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(cookies, gbc);
frame.add(click, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
new Main();
}
});
}
}
Set the text of the JLabel in the actionPerformed method like this:
click.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
numCookies = numCookies + 1;
cookies.setText("Cookies:" + numCookies);
}
});

Adding Text In a New Window

I'm in a bit of a situation here.I'm making a new program, when you click on the menu bar it opens a new window for the Licence, now here is the problem, how would I add text into that new window, here is my code for the new window:
JFrame frame = new JFrame("Licence");
frame.setSize(500,120);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
I know this is a easy question, I just can't think of the correct code for it.
You can try something like
JDialog dialog = new JDialog(your_frame_reference, "Licence");
dialog .setModal(true);
dialog .setLocationRelativeTo(null);
dialog. getContentPane().add(new JLabel(your_text);
dialog .setVisible(true);
You can use label
JFrame frame = new JFrame("Licence");
JLabel label = new JLabel("Text-Only Label");
label.setFont(new Font("Serif", Font.PLAIN, 36));
frame.add(label);
You can add text by creating JLabels like so:
JLabel label = new JLabel("Hello World");
This can then be added to your JFrame.
Try this Example
import java.awt.BorderLayout;
import java.awt.Window;
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.SwingUtilities;
public class TestDialog {
protected static void initUI() {
JPanel pane = newPane("Label in frame");
JFrame frame = new JFrame("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setVisible(true);
}
public static JPanel newPane(String labelText) {
JPanel pane = new JPanel(new BorderLayout());
pane.add(newLabel(labelText));
pane.add(newButton("Open dialog"), BorderLayout.SOUTH);
return pane;
}
private static JButton newButton(String label) {
final JButton button = new JButton(label);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window parentWindow = SwingUtilities.windowForComponent(button);
JDialog dialog = new JDialog(parentWindow);
dialog.setLocationRelativeTo(button);
dialog.setModal(true);
dialog.add(newPane("Label in dialog"));
dialog.pack();
dialog.setVisible(true);
}
});
return button;
}
private static JLabel newLabel(String label) {
JLabel l = new JLabel(label);
l.setFont(l.getFont().deriveFont(24.0f));
return l;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initUI();
}
});
}
}

stopCellEditing on JDialog

My question is similar to this one: JTable Cell Update doesn't work.
However, I am using JDialog instead of a JTable specified in above link. I have a custom class which extends JDialog. I use JEditorPane as a text-component in that dialog and create simple OK, Cancel buttons. Now the problem is, when I enter something in the JEdiorPane and presses OK button, the value is not applied to the text-component until I move the focus out of a JDialog or hit tab/ENTER.
I want the container to be notified that I am done with editing as soon as I press the OK button. In short I want to explicitly have a feature similar to stopCellEditing(). How can I do that?
See this example which seems to work correctly and does the same thing as you described:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class TestEditorPaneDialog {
public void init() {
final JFrame frame = new JFrame();
JButton clickMe = new JButton("Click me");
clickMe.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showDialog(frame);
}
});
frame.add(clickMe);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
showDialog(frame);
}
private void showDialog(final JFrame frame) {
final JDialog dialog = new JDialog(frame, true);
final JEditorPane pane = new JEditorPane();
pane.setText("Type something here");
JPanel south = new JPanel();
JPanel buttons = new JPanel(new GridLayout(1, 0, 10, 10));
JButton ok = new JButton("OK");
ok.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
JOptionPane.showMessageDialog(frame, "You have typed in: " + pane.getText());
}
});
JButton cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
buttons.add(ok);
buttons.add(cancel);
south.add(buttons);
dialog.add(new JScrollPane(pane));
dialog.add(south, BorderLayout.SOUTH);
dialog.setSize(250, 150);
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestEditorPaneDialog().init();
}
});
}
}

Categories