Creating a java swing album - java

I'd like to create a Java Swing Photo Album but I can't manage to find the right way to do it. I think it should be to create two ArrayList, one to stock the photo objects and another one to stock the buttons.
After that I should find a way to assign each images to the buttons and add them into the panel.
My question is : Do you think it is the right way to do it and if so, could you give me a hint? (For the last class at the bottom)
Here's my code at the moment :
Main :
import javax.swing.JFrame;
public class Main extends JFrame {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new AlbumFrame();
}
});
}
}
AlbumFrame :
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AlbumFrame extends JFrame {
private JPanel MenuPanel;
private JPanel PhotoPanel;
public AlbumFrame(){
super("JPhone");
setLayout(new BorderLayout());
PhotoPanel = new PhotoPanel();
add(PhotoPanel,BorderLayout.CENTER);
MenuPanel = new MenuPanel();
add(MenuPanel,BorderLayout.SOUTH);
setSize(480,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
MenuPanel
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MenuPanel extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private JButton backButton;
private JButton homeButton;
private JButton turnButton;
private JButton addButton;
final private JFileChooser fc;
public MenuPanel(){
fc = new JFileChooser();
backButton = new JButton(new ImageIcon(getClass().getResource("/Images/back.png")));
homeButton = new JButton(new ImageIcon(getClass().getResource("/Images/home.png")));
turnButton = new JButton(new ImageIcon(getClass().getResource("/Images/turn.png")));
addButton = new JButton(new ImageIcon(getClass().getResource("/Images/add.png")));
backButton.setPreferredSize(new Dimension(55,55));
homeButton.setPreferredSize(new Dimension(55,55));
turnButton.setPreferredSize(new Dimension(55,55));
addButton.setPreferredSize(new Dimension(55,55));
backButton.addActionListener(this);
homeButton.addActionListener(this);
turnButton.addActionListener(this);
addButton.addActionListener(this);
setLayout(new FlowLayout(FlowLayout.CENTER));
add(backButton);
add(homeButton);
add(turnButton);
add(addButton);
}
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton)e.getSource();
//Test for the moment
if(clicked == backButton){
System.out.println("back");
}else if(clicked == homeButton){
System.out.println("home");
}else if(clicked == turnButton){
System.out.println("turn");
}else if(clicked == addButton){
int returnVal = fc.showOpenDialog(MenuPanel.this);
if(returnVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
}
}
}
}
PhotoPanel
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PhotoPanel extends JPanel implements ActionListener {
ArrayList<Photo> Album = new ArrayList<Photo>();
ArrayList<JButton> Buttons = new ArrayList<JButton>();
public PhotoPanel(){
setLayout(new FlowLayout(FlowLayout.CENTER));
}
public void actionPerformed(ActionEvent e) {
}
}

I would use separate class like PhotoCard to avoid lists:
class PhotoCard {
public PhotoCard(Photo photo) {
add(photo);
// also add buttons, listeners, etc.
}
}
that holds necessary data and initializes listeners.
And then class can be added to to your PhotoPanel:
PhotoPanel.add(new PhotoCard(...));

Related

Best way to access variables from another class?

I need to access variables from another class and I have done it using 2 different approaches described below.
My question is which of the two is preferable and why since both work quite nicely -or is there another better way to do it?. I have also done it using internal classes but this is inconvenient when the number of code lines gets growing ever larger.
In the following test code the commented asterisks repesent different files:
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MainFrame f = new MainFrame("Testing",50,50);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
//**********************************************************************
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class MainFrame extends JFrame {
public MainFrame(String title,int x,int y) {
setTitle(title);
this.setLocation(x, y);
UpperPanel pUp=new UpperPanel();
add(pUp, BorderLayout.NORTH);
LowerPanel pLow=new LowerPanel();
add(pLow, BorderLayout.SOUTH);
pack();
}
}
Now as you can see below UpperPanel must access JButtons from LowerPanel and LowerPanel must access the menu from UpperPanel. For this reason I could pass pUp as a parameter to the LowerPanel constructor but I can't pass pLow as parameter to UpperPanel as it hasn't been created yet.
Therefore I have used 2 methods, one declaring instances of the relevant classes and the other using static variables. The previous 2 classes above are the same in each approach.
Below is the code of the panels in the first case:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JPanel;
public class LowerPanel extends JPanel implements ActionListener {
static JButton butEnableMenu;
static JButton butEnableBut1;
public LowerPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
butEnableMenu=new JButton("Enable menu");
butEnableMenu.setEnabled(true);
butEnableMenu.addActionListener(this);
add(butEnableMenu);
butEnableBut1=new JButton("Enable first button");
butEnableBut1.setEnabled(false);
butEnableBut1.addActionListener(this);
add(butEnableBut1);
}
public void actionPerformed(ActionEvent e) {
UpperPanel up = null;
Object clicked=e.getSource();
JMenu mnu=up.myMenuBar.getMenu(0);
if(clicked.equals(butEnableMenu)) {
mnu.setEnabled(true);
butEnableMenu.setEnabled(false);
}
else if(clicked.equals(butEnableBut1)) {
butEnableMenu.setEnabled(true);
butEnableBut1.setEnabled(false);
}
}
}
//**********************************************************************
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class UpperPanel extends JPanel {
static JMenuBar myMenuBar;
public UpperPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
myMenuBar=new JMenuBar();
JMenu but2=new JMenu("2nd button");
JMenuItem enableBut2=new JMenuItem("Enable");
but2.setEnabled(false);
enableBut2.addActionListener(new menuActionListener());
myMenuBar.add(but2);
but2.add(enableBut2);
add(myMenuBar);
}
}
class menuActionListener implements ActionListener {
static String clickedMenuItem=null;
LowerPanel lp;
public void actionPerformed(ActionEvent e) {
clickedMenuItem=e.getActionCommand();
JMenuItem mnuItm=(JMenuItem)e.getSource();
JPopupMenu pmen = (JPopupMenu)mnuItm.getParent();
JMenu pmnu =(JMenu)pmen.getInvoker();
if(clickedMenuItem.equals("Enable")) {
pmnu.setEnabled(false);
lp.butEnableBut1.setEnabled(true);
}
}
}
And these are the panels in the second case:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class UpperPanel extends JPanel {
static JMenuBar myMenuBar;
public UpperPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
myMenuBar=new JMenuBar();
JMenu but2=new JMenu("2nd button");
JMenuItem enableBut2=new JMenuItem("Enable");
but2.setEnabled(false);
enableBut2.addActionListener(new menuActionListener());
myMenuBar.add(but2);
but2.add(enableBut2);
add(myMenuBar);
}
}
class menuActionListener implements ActionListener {
static String clickedMenuItem=null;
public void actionPerformed(ActionEvent e) {
clickedMenuItem=e.getActionCommand();
JMenuItem mnuItm=(JMenuItem)e.getSource();
JPopupMenu jpm = (JPopupMenu)mnuItm.getParent();
JMenu pmnu =(JMenu)jpm.getInvoker();
if(clickedMenuItem.equals("Enable")) {
pmnu.setEnabled(false);
LowerPanel.butEnableBut1.setEnabled(true);
}
}
}
//**********************************************************************
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JPanel;
public class LowerPanel extends JPanel implements ActionListener {
static JButton butEnableMenu;
static JButton butEnableBut1;
public LowerPanel() {
setLayout(new FlowLayout(FlowLayout.LEFT));
butEnableMenu=new JButton("Enable menu");
butEnableMenu.setEnabled(true);
butEnableMenu.addActionListener(this);
add(butEnableMenu);
butEnableBut1=new JButton("Enable first button");
butEnableBut1.setEnabled(false);
butEnableBut1.addActionListener(this);
add(butEnableBut1);
}
public void actionPerformed(ActionEvent e) {
Object clicked=e.getSource();
JMenu mnu=UpperPanel.myMenuBar.getMenu(0);
if(clicked.equals(butEnableMenu)) {
mnu.setEnabled(true);
butEnableMenu.setEnabled(false);
}
else if(clicked.equals(butEnableBut1)) {
butEnableMenu.setEnabled(true);
butEnableBut1.setEnabled(false);
}
}
}
In general there are 2 ways to access a variable from another class:
You create an object of that class. Then this object has all the variables from the scope of that class assigned to it. For example:
Test t = new Test();
t.name = "test";
You can also create a static variable. Then the variable is assigned to the class not the object of that class. This way you will not need to create an object, but all instances of the class will share the same variable.
//In the scope of the class
static String name;
-------------------------
//when classing the class
Test.name = "The Name of the Test";
If you do not want to create a new instance of a class every time, and always use the same instance, you can create a singleton object. You write a getter method that gets you the object. It looks like this:
public class Test {
Test t;
public static void main(String[] args) {
t = new Test();
}
public Test getTest() {
if (t != null) {
return t;
} else {
t = new Test();
return t;
}
}
}
I see you work with a JFrame. Then you will probably want to make it a singleton. Else you will open a new instance of the JFrame every time you call upon it, which is not recommended.
Does this answer your question?

How to call this method into my other file?

I want to be able to call the Introduction.Intro() method into my main file code, but it tells me I am unable to call a non-static method intro from a static context. Since I am still fairly new to coding I'm not entirely sure what the problem is. I've added my codes down below. I've tried countless online methods but sadly none have seemed to work.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Start extends JFrame implements ActionListener
{
private JFrame Main;
private JPanel PanelA, PanelB, PanelC;
private JLabel Text, ImageL;
private JButton Button;
private ImageIcon Image;
public Start ()
{
//Button
Button = new JButton("Start");
Button.addActionListener(new ButtonListener());
//Text
Text = new JLabel("Welcome To The Game"); //ADD NAME OF THE GAME
//Image
Image = new ImageIcon(getClass().getResource("download.jfif")); //ADD THE IMAGE FOR WELCOME
ImageL = new JLabel(Image);
//Top Panel (PanelA) - Image
PanelA = new JPanel();
PanelA.setBorder(BorderFactory.createEmptyBorder(0,200,150,200));
PanelA.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelA.add(ImageL);
//Middle Panel (PanelB) - Text
PanelB = new JPanel();
PanelB.setBorder(BorderFactory.createEmptyBorder(50,200,10,200));
PanelB.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelB.add(Text);
//Bottom Panel (PanelC) - Buttons
PanelC = new JPanel();
PanelC.setBorder(BorderFactory.createEmptyBorder(0,200,20,200));
PanelC.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelC.add(Button);
//Main Frame
Main = new JFrame ();
Main.add(PanelA, BorderLayout.NORTH);
Main.add(PanelB, BorderLayout.CENTER);
Main.add(PanelC, BorderLayout.SOUTH);
Main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Main.setTitle("GAME TITLE"); //ADD THIS LATER
Main.pack();
Main.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae)
{
}
public class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == Button)
{
Introduction.Intro1(); //THESE LINE RIGHT HERE
return null; //THESE LINE RIGHT HERE
}
}
}
public static void main(String[] args)
{
new Start();
}
}
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Introduction
{
private JFrame Main;
private JPanel PanelD;
private JLabel Text, ImageL;
private JButton Button;
private ImageIcon Image;
public void Intro()
{
Image = new ImageIcon(getClass().getResource("guy.jfif"));
ImageL = new JLabel(Image);
PanelD = new JPanel();
PanelD.setBorder(BorderFactory.createEmptyBorder(0,100,10,100));
PanelD.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelD.add(ImageL);
PanelD.setVisible(true);
Main.add(PanelD, BorderLayout.NORTH);
}
}
EDIT: So I made another method in the Introduction class where I added this line of code, it managed to fix the error, however, the panel isn't being saved and my JFrame is outputting blank.
public static JFrame Intro1()
{
Introduction M = new Introduction();
return M;
}
If you are looking to initialize the Introduction class in main method of Start class, You can add belo code in main method after Start()
Introduction M = new Introduction();
You main method becomes :
public static void main(String[] args)
{
new Start();
Introduction M = new Introduction();
m.Intro
}
Looking at this set of code, It looks like there is incompatible issue, as you have declare JFrame as return type, while you are returning instance of Introduction.
public static JFrame Intro1()
{
Introduction M = new Introduction();
return M;
}

Clear a JLabel with a Jbutton

I am actually a beginner in Java Programming (on eclipse and without netbeans), and want to clear a JLabel presents in a JFrame by clicking a JButton without removing the JButton present at the top of this frame.
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import javax.swing.BoundedRangeModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ButtonTest extends JPanel implements ActionListener {
private JButton ouvrirButton = new JButton("Ouvrir");
private JButton retirerButton = new JButton("Retirer");
private JButton ajouterButton = new JButton("Ajouter");
public ButtonTest() {
add(ouvrirButton);
add(retirerButton);
add(ajouterButton);
ouvrirButton.addActionListener(this);
retirerButton.addActionListener(this);
ajouterButton.addActionListener(this);}
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
Color color = getBackground();
// ACTION Button "OUVRIR"
// I WANT TO REMOVE THIS JLABEL TEXT WHEN I CLICK FOR EXEMPLE ON
// OR "RETIRER"
if (source == ouvrirButton)
{
color = Color.yellow;
JLabel lab1 = new JLabel("Text", JLabel.LEFT);
setLayout(new FlowLayout());
add(lab1 = new JLabel("INVENTAIRE : "));
lab1.setBounds(20, 15, 500, 100);
}
else if (source == retirerButton)
color = Color.red;
else if (source == ajouterButton)
color = Color.red;
setBackground(color);
repaint();
}
// The main
public static void main(String[] args) {
// NOM DE LA FENETRE
JFrame frame = new JFrame("Programme ");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = frame.getContentPane();
contentPane.add(new ButtonTest());
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1300, 700);
frame.setVisible(true);
}
}
I tried .setText("") but it doesn't work... Please help me !
I tried .setText("") but it doesn't work...
Yes it does. The problem is you create the label in the ActionListener so that label reference is only valid in the block of code that created it.
You need to create the label as an instance variable (the way you did for all you buttons) and add the label to the fame at the same time you add the buttons to the panel.
Then you will be able to access the label in the ActionListener and change the text.

How to hide Swing accelerators by a text pane?

I have a Swing application with multiple panes. Some of the panes are text ones (JTextPane), some are dialog-like (with buttons and sliders) and some are graphical (custom painted ). I have a few actions defined in the main menu with simple accelerators like K, P or O.
I would like those accelerators to be processed by the menu actions only if the currently focused pane is not processing them. Specifically, I do not want them to be processed by the menu when the user is just typing in a text pane.
I am creating actions and menu items using:
action = new javax.swing.AbstractAction
new MenuItem(action)
I am registering accelerators with:
action.putValue(javax.swing.Action.ACCELERATOR_KEY, keyStroke)
Is it possible to "eat" (suppress) the key press event for the keys which are processed in the text panes so that they are not passed to the main menu for the global processing?
If not, are there some alternatives to do something similar, like to register the accelerators I know should not be processed when in a text pane for some panes only?
I am adding a code based on an answer to make the question clearer (and to make developing alternate solutions easier):
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
public class TestMenuBindings {
public static void main(String[] args) {
JMenuBar menuBar = new JMenuBar();
final JMenu menu = new JMenu("Print");
final Action oAction = new PrintAction("O",KeyStroke.getKeyStroke(KeyEvent.VK_O, 0));
menu.add(oAction);
menuBar.add(menu);
JFrame frm = new JFrame("Frame");
frm.setJMenuBar(menuBar);
JTextArea area = new JTextArea("Here I want no accelerators", 10, 40);
frm.add(new JScrollPane(area));
frm.add(new JTextField("Here I want accelerators working"), BorderLayout.SOUTH);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
}
private static class PrintAction extends AbstractAction {
private String str;
public PrintAction(String aPrintStr, KeyStroke aMnemonic) {
super("Print: " + aPrintStr);
str = aPrintStr;
putValue(Action.ACCELERATOR_KEY, aMnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(str);
}
}
}
Here is the example. In text area no key bindings working. In text field work all key bindings. Also all the menu items are accessible (enabled) from the menu.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
public class TestMenuBindings {
public static void main(String[] args) {
JMenuBar menuBar = new JMenuBar();
final JMenu menu = new JMenu("Print");
menu.add(new PrintAction("O", KeyStroke.getKeyStroke(KeyEvent.VK_O, 0)));
menu.add(new PrintAction("K", KeyStroke.getKeyStroke(KeyEvent.VK_K, 0)));
menu.add(new PrintAction("P", KeyStroke.getKeyStroke(KeyEvent.VK_P, 0)));
menuBar.add(menu);
JFrame frm = new JFrame("Frame");
frm.setJMenuBar(menuBar);
JTextArea area = new JTextArea("Here working no accelerators", 10, 40);
area.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
setItemStatus(menu, true);
}
#Override
public void focusGained(FocusEvent e) {
setItemStatus(menu, false);
}
});
frm.add(new JScrollPane(area));
frm.add(new JTextField("Here working accelerators"), BorderLayout.SOUTH);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
}
private static void setItemStatus(JMenu aMenu, boolean aStatus) {
for (Component item : aMenu.getMenuComponents()) {
((JMenuItem) item).getAction().setEnabled(aStatus);
}
}
private static class PrintAction extends AbstractAction {
private String str;
public PrintAction(String aPrintStr, KeyStroke aMnemonic) {
super("Print: " + aPrintStr);
str = aPrintStr;
putValue(Action.ACCELERATOR_KEY, aMnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(str);
}
}
}
Here is a solution using KeyBindinds, as suggested by camickr. It is shorter than the one provided by Sergiy Medvynskyy, and I find it more straightforward, but it has a drawback the shortcut is not displayed in the menu, which is a result of the shortcut not being defined in the action itself.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
public class TestMenuBindings {
public static void main(String[] args) {
JMenuBar menuBar = new JMenuBar();
final JMenu menu = new JMenu("Print");
final Action oAction = new PrintAction("O");
menu.add(oAction);
menuBar.add(menu);
JFrame frm = new JFrame("Frame");
frm.setJMenuBar(menuBar);
JTextArea area = new JTextArea("Here working no accelerators", 10, 40);
frm.add(new JScrollPane(area));
frm.add(new JTextField("Here working accelerators") {
{
getInputMap(WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_O, 0), "command_O");
getActionMap().put("command_O", oAction);
}
}, BorderLayout.SOUTH);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
}
private static class PrintAction extends AbstractAction {
private String str;
public PrintAction(String aPrintStr) {
super("Print: " + aPrintStr);
str = aPrintStr;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(str);
}
}
}
It is possible to use KeyEventDispatcher to filter key events.
(Credit: I have adapted the code from answer to Application wide keyboard shortcut)
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class TestMenuBindings {
public static void main(String[] args) {
JMenuBar menuBar = new JMenuBar();
final JMenu menu = new JMenu("Print");
final Action oAction = new PrintAction("O",KeyStroke.getKeyStroke(KeyEvent.VK_O, 0));
menu.add(oAction);
menuBar.add(menu);
JFrame frm = new JFrame("Frame");
frm.setJMenuBar(menuBar);
final JTextArea area = new JTextArea("Here working no accelerators", 10, 40);
frm.add(new JScrollPane(area));
frm.add(new JTextField("Here working accelerators"), BorderLayout.SOUTH);
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
kfm.addKeyEventDispatcher( new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
// pass only KEY_TYPED for letters with no modifiers in the editing area, suppress KEY_PRESSED, KEY_RELEASED
return area.isFocusOwner() && keyStroke.getModifiers()==0 && e.getID()!=KeyEvent.KEY_TYPED && Character.isLetter(e.getKeyChar());
}
});
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setVisible(true);
}
private static class PrintAction extends AbstractAction {
private String str;
public PrintAction(String aPrintStr, KeyStroke aMnemonic) {
super("Print: " + aPrintStr);
str = aPrintStr;
putValue(Action.ACCELERATOR_KEY, aMnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(str);
}
}
}

Displaying image on clicking JButton

Im trying to display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import java.awt.*;
public class new2 extends JFrame implements ActionListener
{
private boolean b1,b2;
Container contentPane= getContentPane();
JButton awar=new JButton("#war");
JButton arrow=new JButton("arrow");
private Image image1,image2;
public new2()
{
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane.setLayout(new FlowLayout());
awar.addActionListener(this);
contentPane.add(awar).setVisible(true);
arrow.addActionListener(this);
contentPane.add(arrow).setVisible(true);
}
public void init()
{
image1=Toolkit.getDefaultToolkit().getImage("#war.jpeg");
image2=Toolkit.getDefaultToolkit().getImage("arrow.gif");
}
public void paint(Graphics g)
{
if(b1==true)
{
g.drawImage(image1,0,0,this);
}
else if(b2==true)
{
g.drawImage(image2,0,0,this);
}
}
public void actionPerformed(ActionEvent event)
{
String actionCommand = event.getActionCommand();
if(actionCommand.equals("#war"))
{
b1=true;
}
else if(actionCommand.equals("arrow"))
{
b2=true;
}
}
public static void main(String args[])
{
new2 m=new new2();
m.setVisible(true);
}
}
..display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
Use a JToggleButton as shown here.
The buttons should set the boolean variables, but your paint2 is never called after the action preformed method. Secondly, it doesn't really even paint anything, it never gets graphics and will cause NPEs.
You should override the JFrame.paint(Graphics g) method.
Whenever you want to refresh the content of the JFrame instance call the JFrame.repaint() method.
/**
*
*/
package com.samples;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
/**
* #author
*
*/
public class MyFrame extends JFrame implements ActionListener {
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
private Image image = null;
private boolean showImage = false;
public MyFrame(String filename) {
setTitle("MyWindow");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
this.image = new ImageIcon(filename).getImage();
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(createControls(), BorderLayout.SOUTH);
}
private JPanel createControls() {
JButton showButton = new JButton("Show");
showButton.addActionListener(this);
showButton.setActionCommand(SHOW_ACTION);
JButton hideButton = new JButton("Hide");
hideButton.addActionListener(this);
hideButton.setActionCommand(HIDE_ACTION);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add(showButton);
panel.add(hideButton);
return panel;
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (showImage) {
g.drawImage(image, 0, 0, image.getWidth(null), image.getHeight(null), null);
}
}
#Override
public void actionPerformed(ActionEvent event) {
String actionCommand = event.getActionCommand();
if (SHOW_ACTION.equals(actionCommand)) {
showImage = true;
} else if (HIDE_ACTION.equals(actionCommand)) {
showImage = false;
}
repaint();
}
/**
* #param args
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MyFrame frame = new MyFrame("resources/image.jpg");
frame.setVisible(true);
}
});
}
}

Categories

Resources