Designing a questionary, the scope of answer can be elected by radioButtons.
To display a greater clickable area (the application is for touchscreen), I layed icon_1 over the radiobuttons.
Every mouseclick can change the displayed icon to icon_2 and permantly vice versa.
I am sorry, using
jRadioButtonActionPerformed
ImageIcon o_ButtonIcon = new ImageIcon ("....")
jRadioButton.setIcon(Icon m_ButtonIcon).
I get no changing, clickable image.
Can you please give me a helping hand?
Seems to be working fine.
Post an SSCCE to show specific problems.
Here is example ( i do not recommend getScaledInstance(..) just used it for quick example)
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class Test {
private ImageIcon ii1;
private ImageIcon ii2;
private JRadioButton jrb = new JRadioButton("Click me :)");
private JFrame frame = new JFrame();
public Test() {
try {
ii1 = new ImageIcon(ImageIO.read(new URL("http://cdn.macrumors.com/article/2010/09/03/145454-itunes_10_icon.jpg")).getScaledInstance(48, 48, Image.SCALE_SMOOTH));
ii2 = new ImageIcon(ImageIO.read(new URL("http://www.quarktet.com/Icon-small.jpg")).getScaledInstance(48, 48, Image.SCALE_SMOOTH));
} catch (Exception ex) {
ex.printStackTrace();
}
initComponents();
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
private void initComponents() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jrb.setIcon(ii1);
jrb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (jrb.getIcon() == ii1) {
jrb.setIcon(ii2);
} else {
jrb.setIcon(ii1);
}
}
});
frame.add(jrb);
frame.pack();
frame.setVisible(true);
}
}
Related
I am creating a NotePad app in Java Swing but when I am trying to open a popup to set a title, it is not showing up.
The class that calls the popup:
import java.io.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
public class NewFile implements ActionListener{
public static String title;
public void actionPerformed(ActionEvent e){
PopupFileName popup = new PopupFileName();
/*try{
Thread.sleep(30000);
}catch (InterruptedException o){
o.printStackTrace();
}*/
JTextArea titl = popup.title;
title = titl.getText();
try{
File writer = new File(title+".txt");
if(writer.createNewFile()){
System.out.println("file created");
}else{
System.out.println("file exists");
}
}catch (IOException i) {
System.out.println("An error occurred.");
i.printStackTrace();
}
}
}
The popup class that is supposed to open:
import javax.swing.*;
public class PopupFileName{
static JFrame popup = new JFrame("File Title");
static JLabel titlel = new JLabel("Title:");
static public JTextArea title = new JTextArea();
public static void main(String[] args){
popup.setSize(200,300);
popup.setVisible(true);
popup.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
popup.add(titlel);
popup.add(title);
}
}
Is there any way I can make it visible and make it able to get the text before it is created?
Start by taking a look at:
Creating a GUI With Swing
How to Write an Action Listener
How to Use Scroll Panes
How to Use Buttons, Check Boxes, and Radio Buttons
How to Make Dialogs
You're running in an event driven environment, this means, something happens and then you respond to it.
The problem with your ActionListener is, it's trying to present a window and then, immediately, trying to get some result from it. The problem is, the window probably isn't even present on the screen yet.
What you need is some way to "stop" the code execution until after the user responds. This is where a modal dialog comes in.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
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.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton btn = new JButton("Test");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String title = PopupFileName.getTitle(TestPane.this);
System.out.println(title);
}
});
add(btn);
}
}
public static class PopupFileName extends JPanel {
private JLabel titlel = new JLabel("Title:");
private JTextArea title = new JTextArea(20, 40);
public PopupFileName() {
setLayout(new BorderLayout());
add(titlel, BorderLayout.NORTH);
add(new JScrollPane(title));
}
public String getTitle() {
return title.getText();
}
public static String getTitle(Component parent) {
PopupFileName popupFileName = new PopupFileName();
int response = JOptionPane.showConfirmDialog(parent, popupFileName, "Title", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
switch (response) {
case JOptionPane.OK_OPTION:
return popupFileName.getTitle();
default: return null;
}
}
}
}
I am trying to create an action on a JButton release and I am not sure how to accomplish this. I can make an action just fine when the button is pressed. When the button is pressed it will change the image to a red dot and when released it should change back to a default green dot.
My button press code is below if someone can point me in the direction on how to create an action when the button is released that would be most helpful. Thanks!
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == change1) {
p1a.setIcon(CLR); // THIS IS THE IMAGE WHEN BUTTON PRESSED
// WOULD LIKE TO CHANGE BACK TO DEFAULT IMAGE HERE WHEN BUTTON IS RELEASED
}
}
I'm not looking for an Icon on the button itself to change I am looking for the image to change in a JPanel....same concept though
Nice to have that information available ahead of time
One approach might be to attach a listener to the ButtonModel and monitor for it's state changes...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
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);
}
});
}
public class TestPane extends JPanel {
private Icon normalIcon;
private Icon pressedIcon;
public TestPane() {
setBorder(new EmptyBorder(16, 16, 16, 16));
normalIcon = makeIcon(Color.GREEN);
pressedIcon = makeIcon(Color.RED);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JLabel label = new JLabel(normalIcon);
JButton btn = new JButton("Pressy");
add(btn, gbc);
add(label, gbc);
btn.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = btn.getModel();
if (model.isArmed()) {
label.setIcon(pressedIcon);
} else {
label.setIcon(normalIcon);
}
}
});
}
protected Icon makeIcon(Color color) {
BufferedImage img = new BufferedImage(25, 25, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(color);
g2d.fillOval(0, 0, 25, 25);
g2d.dispose();
return new ImageIcon(img);
}
}
}
When the button is pressed it will change the image to a red dot and when released it should change back to a default green dot.
This can be entirely achieved within the JButton. See things like setPressedIcon(Icon) ..
E.G.
import javax.swing.*;
import java.net.*;
public class ButtonIcons {
ButtonIcons() throws MalformedURLException {
ImageIcon redIcon = new ImageIcon(new URL(
"https://i.stack.imgur.com/wCF8S.png"));
ImageIcon grnIcon = new ImageIcon(new URL(
"https://i.stack.imgur.com/T5uTa.png"));
JButton button = new JButton("Click me!", grnIcon);
button.setPressedIcon(redIcon);
JOptionPane.showMessageDialog(null, button);
}
public static void main(String[] args) {
Runnable r = () -> {
try {
ButtonIcons o = new ButtonIcons();
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
};
SwingUtilities.invokeLater(r);
}
}
I am trying to display different images in 3 different jlables. There is a folder with images in them. I have display the images in the jlable and the image has to change after 60 seconds. No matter what I try I cannot do it. Can somebody help me.
The simple answer is, use a Swing Timer, it allows you to schedule a callback in the future, which is delivered within the context of the Event Dispatching Thread, making it safe to update the UI from, for example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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 {
private JLabel label;
private File[] images;
private int imageIndex;
public TestPane() {
setLayout(new BorderLayout());
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
add(label);
images = new File("...").listFiles();
imageIndex = -1;
nextImage();
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
nextImage();
}
});
timer.start();
}
protected void nextImage() {
if (images.length > 0) {
imageIndex++;
if (imageIndex >= images.length) {
imageIndex = 0;
}
try {
BufferedImage image = ImageIO.read(images[imageIndex]);
label.setIcon(new ImageIcon(image));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
}
Have a look at How to use Swing Timers for more details.
If your images are large or are coming from a slow service (like over the internet), you might consider using a SwingWorker instead, this allows you to perform long running or blocking operations in the background (off the EDT), but which are easier to synchronise updates back to the EDT with. Have a look at Refresh Image in JLabel with Timer for more details
loadingLab=new JLabel("The name is being saved..");
loadPanel.add(loadingLab);
submitBttn=new JButton("Submit");
submitBttn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Submit Button Clicked!!");
try {
//something is wrong in here as it throws an exception
//what is wrong?
frame.setUndecorated(false);
frame.setOpacity(0.55f);
//when above both lines are commented, the code works fine
//but doesnt have transparency
frame.add(loadPanel,BorderLayout.SOUTH);
frame.setVisible(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
I am trying to display transparent JFrame when "submit" button is clicked which displays panel with a JLabel...
I have tried using setOpacity(0.55f), but it throws exception.. what am i doing wrong?
Unfortunately I think there's no way to keep the system window decoration, you will probably have to go with the default one. Since I'm not 100% sure if you want to toggle the opacity of the whole frame or just the frame's background, I've included both functions in my example. (mKorbels answer help you more if you don't want to have a decoration)
Code:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
public class TransparentExample extends JFrame {
public TransparentExample() {
super("TransparentExample");
Color defaultBackground = getBackground();
float defaultOpacity = getOpacity();
JToggleButton button1 = new JToggleButton("Toggle background transparency");
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (button1.isSelected()) {
setBackground(new Color(defaultBackground.getRed(), defaultBackground.getGreen(),
defaultBackground.getBlue(), 150));
} else {
setBackground(defaultBackground);
}
}
});
JToggleButton button2 = new JToggleButton("Toggle opacity of whole frame");
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dispose();
if (button2.isSelected()) {
setOpacity(0.55f);
} else {
setOpacity(defaultOpacity);
}
setVisible(true);
}
});
getContentPane().setLayout(new FlowLayout());
getContentPane().add(button1);
getContentPane().add(button2);
setSize(800, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame.setDefaultLookAndFeelDecorated(true);
TransparentExample frame = new TransparentExample();
frame.setVisible(true);
}
});
}
}
Picture of frame with no togglebutton selected:
Picture of frame with the first togglebutton selected:
Picture of frame with the second togglebutton selected:
#Programmer007 wrote - the exception is "
java.awt.IllegalComponentStateException: The frame is displayable."
please where I can't see any, for more info about the possible exceptions to read,
as mentioned no idea, everything is about your effort, transformed to the SSCCE / MCVE, short, runnable, compilable
.
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class GenericForm extends JDialog {
private static final long serialVersionUID = 1L;
private Timer timer;
private JDialog dialog = new JDialog();
private int count = 0;
public GenericForm() {
dialog.setSize(400, 300);
dialog.setUndecorated(true);
dialog.setOpacity(0.5f);
dialog.setName("Toggling with opacity");
dialog.getContentPane().setBackground(Color.RED);
dialog.setLocation(150, 150);
dialog.setVisible(true);
timer = new javax.swing.Timer(1500, updateCol());
timer.setRepeats(true);
timer.start();
}
private Action updateCol() {
return new AbstractAction("Hello World") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
boolean bol = dialog.getOpacity() < 0.55f;
count += 1;
if (count < 10) {
if (bol) {
dialog.setOpacity(1.0f);
dialog.getContentPane().setBackground(Color.WHITE);
} else {
dialog.setOpacity(0.5f);
dialog.getContentPane().setBackground(Color.RED);
}
} else {
System.exit(0);
}
}
};
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GenericForm();
}
});
}
}
I am trying to make a slideshow program. I want the next slide to appear when I click (There are only two slides not, but I will add more once the errors r sorted out).
The code compiles fine. But when i click, nothing happens.
What could possibly go wrong?
package project;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Frame extends JFrame{
Frame() {
setLayout(new BorderLayout());
ImageIcon slide = new ImageIcon("E:\\Books\\Computer\\Java\\Introduction to Java Programming\\exercise9e\\image\\slide0.jpg");
JLabel slidesLabel = new JLabel(slide);
add(slidesLabel,BorderLayout.CENTER);
slidesLabel.addMouseListener(new ClickListener());
}
public void nextSlide() {
ImageIcon slide = new ImageIcon("E:\\Books\\Computer\\Java\\Introduction to Java Programming\\exercise9e\\image\\slide1.jpg");
JLabel slidesLabel = new JLabel(slide);
add(slidesLabel,BorderLayout.CENTER);
System.out.println("x");
}
public static void main(String args[]) {
Frame frame = new Frame();
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
public class ClickListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
nextSlide();
}
}
}
So, the "main" problem is BorderLayout will only manage a single component within any of the five available locations it manages.
Adding another component into the position tends to cause issues, where the component that was first added won't be displayed, or in your case, will remain and could interfere with the new component
"A" solution would be to re-use the same JLabel for each slide, simply supply a new value for the icon property (or in this example, the text property)
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Frame extends JFrame {
private JLabel slidesLabel = new JLabel("Apple");
public Frame() {
setLayout(new BorderLayout());
add(slidesLabel, BorderLayout.CENTER);
slidesLabel.addMouseListener(new ClickListener());
}
public void nextSlide() {
slidesLabel.setText("Banana");
}
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) {
ex.printStackTrace();
}
Frame frame = new Frame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ClickListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
nextSlide();
}
}
}
This approach would allow you to place each icon into an array and simply have a counter which determines which slide is current, so when you click for the next slide, you simply increment the counter, get the next value from the array and apply it to the label
A better (and more appropriate) solution would be to actually use a CardLayout, see How to Use CardLayout for more details
With icons...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Frame extends JFrame {
private JLabel slidesLabel = new JLabel();
private Icon[] icons;
private int currentSlide = -1;
public Frame() {
try {
// Personally, I'd use File#listFiles to list all the
// images in a directory, but that might be consider
// using our initiative...
icons = new Icon[]{
new ImageIcon(ImageIO.read(new File("..."))),
new ImageIcon(ImageIO.read(new File("..."))),
new ImageIcon(ImageIO.read(new File("...")))
};
slidesLabel.setVerticalAlignment(JLabel.CENTER);
slidesLabel.setHorizontalAlignment(JLabel.CENTER);
setLayout(new BorderLayout());
add(slidesLabel, BorderLayout.CENTER);
slidesLabel.addMouseListener(new ClickListener());
nextSlide();
} catch (IOException exp) {
exp.printStackTrace();
}
}
public void nextSlide() {
if (currentSlide < icons.length - 1) {
currentSlide++;
slidesLabel.setIcon(icons[currentSlide]);
}
}
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) {
ex.printStackTrace();
}
Frame frame = new Frame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ClickListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
nextSlide();
}
}
}
Why simply adding components to a BorderLayout is bad...
All I did was when nextSlide was called, create a new JLabel assign it the next icon and add it to the Frame (which is using a BorderLayout) and then re-sized the frame. Because the labels are transparent, they remain visible...
This is why you shouldn't simply add new components to a BorderLayout, but, in your case, simply update the properties of the existing JLabel to meet the changing needs.