I have created a program in which a window opens which says click to start.When we press start button it opens another window and make it fullscreen. I have add keylistener to this fullscreen window to move an image.But its not working. If you wanna see the code please ask me .
public g1(){
panel = new JPanel();
cake = new ImageIcon("G:\\naman1.jpg").getImage();
start = new JButton("Start");
restart = new JButton("Restart");
exit = new JButton("EXIT");
panel.add(start);
panel.setFocusable(true);
start.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
new g1().run(); //this method is from superclass it calls init }
}
);
panel.setBackground(Color.GRAY);
}
public void init(){
super.init(); //it makes the window fullscreen
Window w = s.getFullScreenWindow();
w.setFocusable(true);
w.addKeyListener(this);}
Try this:
The MainFrame
package moveimages;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
JButton startBtn;
public MainFrame() {
this.setTitle("Moving Images");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(initComponents());
this.setSize(new Dimension(1024, 768));
this.setVisible(true);
}
private JPanel initComponents() {
JPanel jPanel = new JPanel();
startBtn = new JButton("start");
startBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
final ImageWindow imageWindow = new ImageWindow();
}
});
jPanel.add(startBtn);
return jPanel;
}
}
This is the ImageWindow
package moveimages;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class ImageWindow extends JFrame {
public ImageWindow() {
this.add(new JLabel("Window"));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(screenSize.width, screenSize.height);
final ImagePanel imagePanel = new ImagePanel();
this.getContentPane().add(imagePanel);
this.setVisible(true);
}
class ImagePanel extends JPanel {
URL url;
int panelX;
int panelY;
boolean isDragged;
ImagePanel() {
this.panelX = this.getWidth();
this.panelY = this.getHeight();
try {
this.url = new URL("http://i.stack.imgur.com/XZ4V5.jpg");
final ImageIcon icon = new ImageIcon(url);
final JLabel imageLabel = new JLabel(icon);
Action moveLeft = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(imageLabel.getX() - 1 > 0)
imageLabel.setLocation(imageLabel.getX()-1, imageLabel.getY());
}
};
Action moveUp = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(imageLabel.getY() - 1 > 0) {
imageLabel.setLocation(imageLabel.getX(), imageLabel.getY()-1);
}
}
};
Action moveDown = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(getParent().getHeight()-icon.getIconHeight() > imageLabel.getY() + 1) {
imageLabel.setLocation(imageLabel.getX(), imageLabel.getY()+1);
}
}
};
Action moveRight = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(getParent().getWidth()-icon.getIconWidth() > imageLabel.getX()+1) {
imageLabel.setLocation(imageLabel.getX()+1, imageLabel.getY());
}
}
};
imageLabel.getInputMap().put(KeyStroke.getKeyStroke("A"), "moveLeft");
imageLabel.getInputMap().put(KeyStroke.getKeyStroke("W"), "moveUp");
imageLabel.getInputMap().put(KeyStroke.getKeyStroke("S"), "moveDown");
imageLabel.getInputMap().put(KeyStroke.getKeyStroke("D"), "moveRight");
imageLabel.getActionMap().put("moveLeft", moveLeft);
imageLabel.getActionMap().put("moveUp", moveUp);
imageLabel.getActionMap().put("moveDown", moveDown);
imageLabel.getActionMap().put("moveRight", moveRight);
this.add(imageLabel);
} catch (MalformedURLException ex) {
Logger.getLogger(ImageWindow.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Start the App
package moveimages;
import javax.swing.SwingUtilities;
public class MoveImages {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MainFrame frame = new MainFrame();
});
}
}
Maybe it helps you to refactor your current app.
Related
Trying to add a keyListener to this component, however I am getting no response. I want it to be respond whenever the component is displayed in the scroll Panel. I've been able to get it to work when adding it to JPanels. Is there something I should be doing differently for my component?
This the the Component I seek to implement Keylistener on.
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.event.MouseInputListener;
import java.awt.FontMetrics;
import java.awt.event.MouseEvent;
import java.awt.Point;
import java.util.ArrayList;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
public class PhotoComponent extends JComponent implements MouseInputListener{
private ImageIcon pic;
Boolean checkVac=false;
Boolean checkSchool=false;
Boolean checkFam= false;
Boolean checkWork = false;
Boolean flipped = false;
Boolean penButton=false;
boolean textButton=false;
public PhotoComponent(){
}
public PhotoComponent(ImageIcon p){
pic=p;
setRequestFocusEnabled(true);
requestFocus();
addKeyListener(new KeyAdapter(){
public void keyTyped(KeyEvent e) {
System.out.println("hello");
}
});
}
#Override
public Dimension getPreferredSize(){
if(pic==null){
return new Dimension(0,0);
}
return new Dimension(pic.getIconWidth(), pic.getIconHeight());
}
#Override
protected void paintComponent(Graphics g){
pic.paintIcon(this, g, 0, 0);
}
}
This is the program I am calling it on.
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.event.MouseInputListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.io.*;
public class Base extends JFrame {
private JPanel statusContainer;
private JScrollPane scrollPane;
private JMenuBar jmb;
private JMenu file;
private JMenuItem importbutton;
private ArrayList<PhotoComponent> picList;
private int picIndex;
public static void main(String[] args) {
new Base();
}
public Base(){
setTitle("Placeholder");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500,500);
setResizable(true);
mainProgram();
pack();
setVisible(true);
}
public void mainProgram(){
jmb = new JMenuBar();
setJMenuBar(jmb);
file=new JMenu("File");
statusContainer = new JPanel();
add(statusContainer, BorderLayout.SOUTH);
jmb.add(file);
importbutton = new JMenuItem("Import");
//currentPic= new PhotoComponent();
picList= new ArrayList<PhotoComponent>(5);
picIndex = 0;
scrollPane = new JScrollPane();
add(scrollPane);
importbutton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent fo){
JFileChooser chooser= new JFileChooser("");
FileFilter filter = new FileNameExtensionFilter("Graphics", "jpg","jpeg","png");
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.setMultiSelectionEnabled(true);
int response = chooser.showOpenDialog(null);
if(response == JFileChooser.APPROVE_OPTION){
File[] chosen = chooser.getSelectedFiles();
for (File f:chosen) {
if(f.isDirectory()){
File[] temp=f.listFiles();
for (File x:temp){;
ImageIcon ii =new ImageIcon(x.getAbsolutePath());
picList.add(new PhotoComponent(ii));
}
}
else{
ImageIcon ii =new ImageIcon(f.getAbsolutePath());
picList.add(new PhotoComponent(ii));
}
}
scrollPane.setViewportView(picList.get(picIndex));
///mainScroll.addMouseListener(picList.get(pos));
scrollPane.setVisible(true);
validate();
}
else {
JOptionPane.showInputDialog("oops somethings wrong");
}
}
});
file.add(importbutton);
}
}
Ther're many ways how to solve this problem. One of them use KeyEventDispatcher if you need some global key mappings.
Another way is to add KeyListener to you parent JFrame to catch key pressed event and delegate it to the current component. Check this out!
P.S. I am not saying that this is an optimal solution, but I have checked it - it works. You can use it or it can be a start point for your own solution.
public class Base extends JFrame implements ActionListener, KeyListener {
private final JPanel statusContainer = new JPanel();
private final JScrollPane scrollPane = new JScrollPane();
private final JMenuBar menubar = new JMenuBar();
private final JMenu file = new JMenu("File");
private final JMenuItem importButton = new JMenuItem("Import");
private List<PhotoComponent> pictures = Collections.emptyList();
private int pictureIndex = -1;
public static void main(String... args) {
SwingUtilities.invokeLater(() -> new Base().setVisible(true));
}
public Base() {
init();
}
private void init() {
setTitle("Placeholder");
setJMenuBar(menubar);
add(statusContainer, BorderLayout.SOUTH);
add(scrollPane);
file.add(importButton);
menubar.add(file);
setResizable(true);
importButton.addActionListener(this);
addKeyListener(this);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(500, 500);
}
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == importButton)
onImportButton();
}
private void onImportButton() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(new FileNameExtensionFilter("Graphics", "jpg", "jpeg", "png"));
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fileChooser.setMultiSelectionEnabled(true);
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
pictures = getPictures(fileChooser);
pictureIndex = pictures.isEmpty() ? -1 : 0;
scrollPane.setViewportView(pictureIndex == -1 ? null : pictures.get(pictureIndex));
scrollPane.setVisible(true);
validate();
} else
JOptionPane.showInputDialog("oops somethings wrong");
}
private static List<PhotoComponent> getPictures(JFileChooser fileChooser) {
List<PhotoComponent> pictures = new ArrayList<>();
for (File fileOrDir : fileChooser.getSelectedFiles())
for (File file : getFiles(fileOrDir))
pictures.add(new PhotoComponent(new ImageIcon(file.getAbsolutePath())));
return pictures;
}
private static List<File> getFiles(File fileOrDir) {
if (fileOrDir.isDirectory())
return Arrays.asList(Objects.requireNonNull(fileOrDir.listFiles()));
return Collections.singletonList(fileOrDir);
}
#Override
public void keyTyped(KeyEvent event) {
}
#Override
public void keyPressed(KeyEvent event) {
if (pictureIndex != -1)
pictures.get(pictureIndex).keyPressed(event);
}
#Override
public void keyReleased(KeyEvent event) {
}
}
public class PhotoComponent extends JComponent {
private final ImageIcon picture;
public PhotoComponent(ImageIcon picture) {
this.picture = picture;
}
public void keyPressed(KeyEvent event) {
System.out.println("keyPressed: " + event.getKeyCode());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(picture.getIconWidth(), picture.getIconHeight());
}
#Override
protected void paintComponent(Graphics g) {
picture.paintIcon(this, g, 0, 0);
}
}
I have a button. I want to change the background after I click on it. My problem here is the button auto call paintComponent(). How can prevent this? I expect after clicking the button the button will be blue, but it will still be red.
package test;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ButtonDemo extends JButton implements ActionListener{
public ButtonDemo() {
this.setText("BUTTON TEXT");
this.addActionListener(this);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.RED);
}
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel contentPane = new JPanel();
frame.setContentPane(contentPane);
contentPane.add(new ButtonDemo());
frame.setSize(500, 500);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
this.setBackground(Color.BLUE);
}
}
My personal gut feeling is that JButton is probably not suited to your desired goal.
Essentially, you want to control when and how the "selected" state of the piece is changed.
Personally, I would have some kind of controller which monitored the mouse events in some way (probably having the piece component delegate the event back to the controller) and some kind of model which control when pieces become selected, this would then notify the controller of the state change and it would make appropriate updates to the UI.
But that's a long process to setup. Instead, I'm demonstrating a simple concept where a component can be selected with the mouse, but only the controller can de-select. In this example, this will allow only a single piece to be selected
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
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.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridLayout(5, 5));
ChangeListener listener = new ChangeListener() {
private PiecePane selectedPiece;
#Override
public void stateChanged(ChangeEvent e) {
if (!(e.getSource() instanceof PiecePane)) { return; }
PiecePane piece = (PiecePane) e.getSource();
// Want to ignore events from the selected piece, as this
// might interfer with the changing of the pieces
if (selectedPiece == piece) { return; }
if (selectedPiece != null) {
selectedPiece.setSelecetd(false);
selectedPiece = null;
}
selectedPiece = piece;
}
};
for (int index = 0; index < 5 * 5; index++) {
PiecePane pane = new PiecePane();
pane.addChangeListener(listener);
add(pane);
}
}
}
public class PiecePane extends JPanel {
private boolean selecetd;
private Color selectedBackground;
private Color normalBackground;
private MouseListener mouseListener;
public PiecePane() {
setBorder(new LineBorder(Color.DARK_GRAY));
mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
setSelecetd(true);
}
};
setNormalBackground(Color.BLUE);
setSelectedBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
#Override
public void addNotify() {
super.addNotify();
addMouseListener(mouseListener);
}
#Override
public void removeNotify() {
super.removeNotify();
removeMouseListener(mouseListener);
}
public void addChangeListener(ChangeListener listener) {
listenerList.add(ChangeListener.class, listener);
}
public void removeChangeListener(ChangeListener listener) {
listenerList.remove(ChangeListener.class, listener);
}
protected void fireSelectionChanged() {
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
if (listeners.length == 0) {
return;
}
ChangeEvent evt = new ChangeEvent(this);
for (int index = listeners.length - 1; index >= 0; index--) {
listeners[index].stateChanged(evt);
}
}
public boolean isSelected() {
return selecetd;
}
public void setSelecetd(boolean selecetd) {
if (selecetd == this.selecetd) { return; }
this.selecetd = selecetd;
updateSelectedState();
fireSelectionChanged();
}
public Color getSelectedBackground() {
return selectedBackground;
}
public void setSelectedBackground(Color selectedBackground) {
this.selectedBackground = selectedBackground;
updateSelectedState();
}
public Color getNormalBackground() {
return normalBackground;
}
public void setNormalBackground(Color normalBackground) {
this.normalBackground = normalBackground;
updateSelectedState();
}
protected void updateSelectedState() {
if (isSelected()) {
setBackground(getSelectedBackground());
} else {
setBackground(getNormalBackground());
}
}
}
}
I created a toggle button.
You set the primary color and the alternate color in the class constructor.
When you call the switchColors method, the JButton background changes from the primary color to the alternate color. When you call the switchColors method again, the JButton background changes from the alternate color to the primary color.
In the following example, I put the switchColors method in the actionListener so you can see the color change. Each time you left-click on the JButton, the background color changes.
You would call the switchColors method when you want the JButton background to change from blue to red, and again when you want the JButton background to change from red to blue. It's under your control.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ButtonDemo extends JButton
implements ActionListener {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Button Demo");
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
frame.setContentPane(contentPane);
contentPane.add(new ButtonDemo(Color.BLUE,
Color.RED));
frame.setSize(300, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
private boolean primaryBackground;
private Color primaryColor;
private Color alternateColor;
public ButtonDemo(Color primaryColor,
Color alternateColor) {
this.primaryColor = primaryColor;
this.alternateColor = alternateColor;
this.primaryBackground = true;
this.setText("BUTTON TEXT");
this.setBackground(primaryColor);
this.addActionListener(this);
}
public void switchColors() {
primaryBackground = !primaryBackground;
Color color = primaryBackground ? primaryColor :
alternateColor;
this.setBackground(color);
}
#Override
public void actionPerformed(ActionEvent e) {
switchColors();
}
}
If you want to change the background for a short while you can do it with swing Timer:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ButtonDemo extends JButton implements ActionListener{
private static final int DELAY = 600; //milliseconds
private final Timer timer;
public ButtonDemo() {
this.setText("BUTTON TEXT");
this.addActionListener(this);
Color defaultCloor = getBackground();
timer = new Timer(DELAY, e-> setBackground(defaultCloor));
timer.setRepeats(false);
}
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel contentPane = new JPanel();
frame.setContentPane(contentPane);
contentPane.add(new ButtonDemo());
frame.setSize(300, 200);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
this.setBackground(Color.RED);
timer.start();
}
}
I need the frame to update and display how many times the Button has been pressed (the button's text to update)
If I can use actionPreformed() to be locked on to specific events (Button press, or the Menu item being pressed), then I think that should help...
Problems:
When Button is pressed it creates more frames
The existing Frame(s) do not update (I only want there to be one frame anyway)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class ButtonFrame implements InternalFrameListener, ActionListener
{
JFrame myFrame = null;
private int clicked;
final String F=("Clicked: "+clicked+" Times!");
public static void main(String[] a)
{
(new ButtonFrame()).test();
}
private void test()
{
myFrame = new JFrame("Internal Frame with a Button");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(400,400);
myFrame.setContentPane(new JDesktopPane());
JMenuBar Start_Bar = new JMenuBar();
JMenu Start_Menu = new JMenu("Frame");
JMenuItem Start_Item = new JMenuItem("Start");
Start_Item.addActionListener(this);
Start_Menu.add(Start_Item);
Start_Bar.add(Start_Menu);
myFrame.setJMenuBar(Start_Bar);
myFrame.setVisible(true);
}
public void actionPerformed(ActionEvent Start_Item)
{
JInternalFrame f = new JInternalFrame("Button Frame");
f.setResizable(true);
f.setClosable(false);
f.setMaximizable(true);
f.setIconifiable(true);
f.setSize(200,200);
f.setLocation(100,100);
f.addInternalFrameListener(this);
f.setVisible(true);
Button objButton1;
objButton1=new Button ("Clicked: "+clicked+" Times!");
objButton1.setBounds(20,90,40,50);
f.add(objButton1);
objButton1.addActionListener(this);
myFrame.getContentPane().add(f);
}
public void actionPreformed(ActionEvent objButton1)
{
clicked++;
}
public void internalFrameActivated(InternalFrameEvent e)
{
System.out.println("Internal Button Ready");
}
public void internalFrameClosed(InternalFrameEvent e)
{
System.out.println("Internal frame closed");
}
public void internalFrameClosing(InternalFrameEvent e)
{
System.out.println("Internal frame closing");
}
public void internalFrameDeactivated(InternalFrameEvent e)
{
System.out.println("Internal frame deactivated");
}
public void internalFrameDeiconified(InternalFrameEvent e)
{
System.out.println("Internal frame deiconified");
}
public void internalFrameIconified(InternalFrameEvent e)
{
System.out.println("Internal frame iconified");
}
public void internalFrameOpened(InternalFrameEvent e)
{
System.out.println("Internal frame opened");
}
}
Based on your description, you solution is screaming isolation and separation of code responsibility, the code responsible for managing the button should be separated from the code managing the frame and desktop pane
This way, you can use separate ActionListeners as well as isolate the functionality to a single instance of the button class
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.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
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();
}
JDesktopPane dp = new JDesktopPane();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar Start_Bar = new JMenuBar();
JMenu Start_Menu = new JMenu("Frame");
JMenuItem Start_Item = new JMenuItem("Start");
Start_Item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JInternalFrame f = new JInternalFrame("Button", true, true, true, true);
f.setSize(200, 200);
f.setLocation(100, 100);
f.add(new ButtonPane());
f.setVisible(true);
dp.add(f);
}
});
Start_Menu.add(Start_Item);
Start_Bar.add(Start_Menu);
frame.setJMenuBar(Start_Bar);
frame.add(dp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ButtonPane extends JPanel {
private JButton button;
private int count = 0;
public ButtonPane() {
setLayout(new GridBagLayout());
button = new JButton("0");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
count++;
button.setText(Integer.toString(count));
}
});
add(button);
}
}
}
I would like to programmatically expand a particular JMenuItem in a JPopup. For example in the code below
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class AutoExpandSubMenusDemo extends JFrame {
private final JPopupMenu popup = new JPopupMenu("Popup");
public AutoExpandSubMenusDemo() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
JMenu menuB = new JMenu("B");
menuB.add(new JMenuItem("X"));
JMenuItem menuY = menuB.add(new JMenuItem("Y"));
menuB.add(new JMenuItem("Z"));
popup.add(new JMenuItem("A"));
popup.add(menuB);
popup.add(new JMenuItem("C"));
final JButton button = new JButton("Show Popup Menu");
button.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
popup.show(button, 0, button.getHeight());
// Show menuY
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(button);
getContentPane().add(buttonPanel);
}
public static void main(String[] args) {
AutoExpandSubMenusDemo f = new AutoExpandSubMenusDemo();
f.setSize(500, 300);
f.setVisible(true);
}
}
I would like to expand the popup menu so that the items B(menuB)/Y(menuY) are expanded and selected when the button is pressed.
Sorry if this is something that's easy to do but I've searched around and can't figure it out.
I did find the
MenuSelectionManager.defaultManager().setSelectedPath(...)
however this didn't work when I tried it and the javadoc specifies that it is called from the LaF and should not be called by clients.
Any help is much appreciated.
While I don't recommend doing this, since the documentation itself advises against it, here's how you could do it:
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
public class AutoExpandSubMenusDemo extends JFrame {
private final JPopupMenu popup = new JPopupMenu("Popup");
public AutoExpandSubMenusDemo() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
final JMenu menuB = new JMenu("B");
menuB.add(new JMenuItem("X"));
final JMenuItem menuY = menuB.add(new JMenuItem("Y"));
menuB.add(new JMenuItem("Z"));
popup.add(new JMenuItem("A"));
popup.add(menuB);
popup.add(new JMenuItem("C"));
final JButton button = new JButton("Show Popup Menu");
button.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
popup.show(button, 0, button.getHeight());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
menuB.setPopupMenuVisible(true);
MenuSelectionManager.defaultManager().setSelectedPath(new MenuElement[]{popup, menuB, menuY});
}
});
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(button);
getContentPane().add(buttonPanel);
}
public static void main(String[] args) {
AutoExpandSubMenusDemo f = new AutoExpandSubMenusDemo();
f.setSize(500, 300);
f.setVisible(true);
}
}
Most of this code is yours. I only added:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
menuB.setPopupMenuVisible(true);
MenuSelectionManager.defaultManager().setSelectedPath(new MenuElement[]{popup, menuB, menuY});
}
});
which seems to work.
You could avoid abusing MenuSelectionManager via 'MenuItem.setArmed(boolean)'.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
menuB.setPopupMenuVisible(true);
menuB.setArmed(true);
menuY.setArmed(true);
}
});
The popup staying visible after selecting another menu item or dismissing the JPopupMenu still needs to be addressed though.
Another way is to fake a mouse event... :D
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MouseEvent event = new MouseEvent(
menuB, MouseEvent.MOUSE_ENTERED, 0, 0, 0, 0, 0, false);
menuB.dispatchEvent(event);
menuY.setArmed(true);
}
});
This way it is as if the user actually used the mouse.
Another example:
MenuSelectionManager.defaultManager().setSelectedPath(
new MenuElement[] {popup, menuB, menuB.getPopupMenu()});
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AutoExpandSubMenusDemo2 extends JFrame {
private final JPopupMenu popup = new JPopupMenu("Popup");
public AutoExpandSubMenusDemo2() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
final JMenu menuB = new JMenu("B");
menuB.add(new JMenuItem("X"));
final JMenuItem menuY = menuB.add(new JMenuItem("Y"));
menuB.add(new JMenuItem("Z"));
popup.add(new JMenuItem("A"));
popup.add(menuB);
popup.add(new JMenuItem("C"));
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new AbstractAction("Show menuB Popup") {
#Override public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
popup.show(button, 0, button.getHeight());
//[Bug ID: JDK-6949414 JMenu.buildMenuElementArray() endless loop]
//( http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6949414 )
//menuB.doClick();
MenuSelectionManager.defaultManager().setSelectedPath(
new MenuElement[] {popup, menuB, menuB.getPopupMenu()});
}
}));
buttonPanel.add(new JButton(new AbstractAction("Select menuY") {
#Override public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
popup.show(button, 0, button.getHeight());
MenuSelectionManager.defaultManager().setSelectedPath(
new MenuElement[] {popup, menuB, menuB.getPopupMenu(), menuY});
}
}));
getContentPane().add(buttonPanel);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new AutoExpandSubMenusDemo2();
f.setSize(500, 300);
f.setVisible(true);
}
}
What is the best way to add a background image to a JPanel/JLabel when a JButton is called? I know how to get the JButton action and such. I just can't figure out or find a way to get the background image to change when that button is pressed.
Here is an example:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class ModifiableBackgroundFrame extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
private ImageIcon image;
private JPanel pan;
private JButton btn;
private int count = 0;
private static final String[] images =
{"http://www.dvd-ppt-slideshow.com/images/ppt-background/background-3.jpg",
"http://www.psdgraphics.com/wp-content/uploads/2009/02/abstract-background.jpg",
"http://hdwallpaperpics.com/wallpaper/picture/image/background.jpg",
"http://www.highresolutionpics.info/wp-content/uploads/images/beautiful-on-green-backgrounds-for-powerpoint.jpg"};
public ModifiableBackgroundFrame()
{
super("The title");
image = new ImageIcon();
btn = new JButton("Change background");
btn.setFocusPainted(false);
btn.addActionListener(this);
pan = new JPanel()
{
private static final long serialVersionUID = 1L;
#Override
public void paintComponent(Graphics g)
{
g.drawImage(image.getImage(), 0, 0, null);
}
};
pan.setPreferredSize(new Dimension(400, 400));
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(pan, BorderLayout.CENTER);
contentPane.add(btn, BorderLayout.SOUTH);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new ModifiableBackgroundFrame();
}
});
}
#Override
public void actionPerformed(ActionEvent e)
{
btn.setEnabled(false);
btn.setText("Loading...");
new SwingWorker<Image, Void>()
{
#Override
protected Image doInBackground() throws Exception
{
return ImageIO.read(new URL(images[count++ % 4]));
}
#Override
protected void done()
{
try
{
image.setImage(get());
pan.repaint();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
catch(ExecutionException e)
{
e.printStackTrace();
}
btn.setText("Change background");
btn.setEnabled(true);
}
}.execute();
}
}
In your JButton's actionPerformed, you can call JLabel.setIcon(Icon) to set a background image.
final JLabel label = new JLabel();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
label.setIcon(new ImageIcon(SOME_IMAGE));
}
}