I am trying to make simple program, exercise actually - its description is included in attached code. My trouble is that keyPressed() method is completely ignored. Please take a look if possible and provide me with some hints on what I am doing wrong.
class exercise_chapter10_5
/*
White a program that creates a window with a menu bar. The menu bar should have
a single menu that has 10 menu items with text: 0, 1, . . . , 9, respectively. When a user
selects a number from the menu bar, the corresponding number should be displayed
inside the panel of the window. Once finished, add a key listener. When a user types
a digit between 0 and 9, the digit should be displayed in the window. Create an array
to store the menu items.
*/
package exercise;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class exercise_chapter10_5 {
public static void main(String[] args) throws Exception {
MyFrame frame = new MyFrame();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyFrame extends JFrame {
MyPanel p;
public MyFrame() {
setSize(300, 300);
JMenuBar bar = new JMenuBar();
setJMenuBar(bar);
//a window with a menu bar
JMenu numbers = new JMenu(" Numbers ");
bar.add(numbers);
// Create an array to store the menu items
ArrayList<JMenuItem> menuitems = new ArrayList<JMenuItem>();
for (int i = 0; i < 10; i++) {
menuitems.add(new JMenuItem(i + ""));
}
for (int i = 0; i < menuitems.size(); i++) {
numbers.add(menuitems.get(i));
}
// add action listener for every menu item
for (int i = 0; i < menuitems.size(); i++) {
menuitems.get(i).addActionListener(new NumberListener(i));
}
p = new MyPanel();
add(p);
}
class NumberListener implements ActionListener {
private int number;
public NumberListener(int num) {
this.number = num;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
p.changeNumber(number);
}
}
}
class MyPanel extends JPanel {
private int number;
public void changeNumber(int num) {
this.number = num;
repaint();
}
public MyPanel() {
this.setFocusable(true);
this.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
changeNumber((e.getKeyChar() - '0'));
//System.out.println(e.getKeyChar());
System.out.println("In Panel the number typed is: " + number);
repaint();
}
});
System.out.println("Panel was born");
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.getButton() == 1) {
System.out.println("current number is: " + number);
repaint();
}
if (e.getButton() == 3) {// right button was pressed
System.out.println("Right mouse button was pressed");
repaint();
}
}
});
}
public void showMessage(String s, Graphics2D g2) {
Font myFont = new Font(" SansSerif ", Font.BOLD + Font.ITALIC, 40);
g2.setFont(myFont);
g2.setColor(Color.RED);
Rectangle2D textBox = myFont.getStringBounds(s, g2.getFontRenderContext());
g2.drawString(s, (int) (getWidth() / 2 - textBox.getWidth() / 2), (int) (getHeight() / 2 - textBox.getHeight()));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
showMessage(Integer.toString(number), g2);
}
}
Thanks for your hints. What worked for me here is that I had to call setFocusable(true) method within JPanel constructor first.
class MyPanel extends JPanel {
private int number;
public void changeNumber(int num) {
this.number = num;
repaint();
}
public MyPanel() {
this.setFocusable(true);
this.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
changeNumber((e.getKeyChar() - '0'));
//System.out.println(e.getKeyChar());
System.out.println("In Panel the number typed is: " + number);
repaint();
}
});
System.out.println("Panel was born");
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.getButton() == 1) {
System.out.println("current number is: " + number);
repaint();
}
if (e.getButton() == 3) {// right button was pressed
System.out.println("Right mouse button was pressed");
repaint();
}
}
});
}
Related
I want to create a program, where a user clicks on the window, the first mouse press creates a triangle object where p[0](a Point2D.Float variable) has a value set from the mouse press location, which then draws a small dot, the second press creates a point(p[1]) from location on second mouse press then draws a line from point one from first press to point two on second press. The third press creates the third point(p[2]) then draws a line from all 3 points from where mouse was pressed - creating a triangle.
I have done that so far with just 1 triangle but I want to dynamically make more than 1 triangle.
How can I can do that? I am just looking for any help at all, suggestions needed.
import javax.swing.JFrame;
public class Main {
public static void main(String[] args){
Window window = new Window();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(700,500);
window.setLocation(400,100);
window.setTitle("Draw");
window.initialize();
window.setVisible(true);
}
}
Triangle Class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import javax.swing.JPanel;
public class Triangle extends JPanel {
private Point2D.Float[] p = new Point2D.Float[3];
private Color color;
public Triangle(int x, int y, int index){
p[index] = new Point2D.Float(x,y);
}
public void setColor(Color c){
color = c;
}
public Color getColor(){
return color;
}
public void setPoint(int x, int y, int index){
p[index] = new Point2D.Float(x,y);
}
public void draw(Graphics2D g){
g.setColor(color);
if(p[0] != null && p[1] == null && p[2] == null){
g.fill(new Ellipse2D.Float((int)p[0].x,(int)p[0].y,3,3));
}else if(p[0] != null && p[1] != null && p[2] == null){
g.drawLine((int)p[0].x, (int)p[0].y, (int)p[1].x,(int)p[1].y);
}else if(p[0] != null && p[1] != null && p[2] != null){
g.drawLine((int)p[0].x, (int)p[0].y, (int)p[1].x,(int)p[1].y);
g.drawLine((int)p[0].x, (int)p[0].y, (int)p[2].x,(int)p[2].y);
g.drawLine((int)p[1].x, (int)p[1].y, (int)p[2].x,(int)p[2].y);
}
repaint();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
draw(g2);
}
}
Window Class
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
public class Window extends JFrame {
private JRadioButton redRadioButton, blueRadioButton, greenRadioButton,
blackRadioButton;
private Container contentPane;
private Triangle triangle;
private JPanel colorPanel;
private JPanel clearPanel;
private JButton clearButton;
private ButtonGroup buttonGroup;
private int index = 0;
private int mousePressed = 0;
private Color c;
public void initialize(){
contentPane = getContentPane();
buttonGroup = new ButtonGroup();
colorPanel = new JPanel();
clearPanel = new JPanel();
clearButton = new JButton("CLEAR");
triangle = new Triangle();
triangle.addMouseListener(new MouseGuide());
clearButton.setFocusable(false);
ButtonListener buttonListener = new ButtonListener();
clearButton.addActionListener(buttonListener);
redRadioButton = new JRadioButton("RED");
redRadioButton.setFocusable(false);
redRadioButton.setSelected(true);
redRadioButton.addActionListener(buttonListener);
blueRadioButton = new JRadioButton("BLUE");
blueRadioButton.setFocusable(false);
blueRadioButton.addActionListener(buttonListener);
greenRadioButton = new JRadioButton("GREEN");
greenRadioButton.setFocusable(false);
greenRadioButton.addActionListener(buttonListener);
blackRadioButton = new JRadioButton("BLACK");
blackRadioButton.setFocusable(false);
blackRadioButton.addActionListener(buttonListener);
buttonGroup.add(redRadioButton);
buttonGroup.add(blueRadioButton);
buttonGroup.add(greenRadioButton);
buttonGroup.add(blackRadioButton);
colorPanel.add(redRadioButton);
colorPanel.add(blueRadioButton);
colorPanel.add(greenRadioButton);
colorPanel.add(blackRadioButton);
clearPanel.add(clearButton);
colorPanel.setBorder(new TitledBorder(new EtchedBorder(), "Pick a Color"));
contentPane.add("North", colorPanel);
contentPane.add("Center", triangle);
contentPane.add("South",clearPanel);
System.out.println(index);
}
public void setShapeColor(){
if(redRadioButton.isSelected()){
c = Color.RED;
contentPane.revalidate();
contentPane.repaint();
}else if(blueRadioButton.isSelected()){
c = Color.BLUE;
triangle.setColor(c);
contentPane.revalidate();
contentPane.repaint();
}else if(greenRadioButton.isSelected()){
c = Color.GREEN;
contentPane.revalidate();
contentPane.repaint();
}else if(blackRadioButton.isSelected()){
c = Color.BLACK;
contentPane.revalidate();
contentPane.repaint();
}
}
public class ButtonListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent ae) {
setShapeColor();
Object source = ae.getSource();
if(source == clearButton){
mousePressed = 0;
index = 0;
}
}
}
public class MouseGuide implements MouseListener{
#Override
public void mouseClicked(MouseEvent me) {
}
#Override
public void mousePressed(MouseEvent me) {
mousePressed++;
if(mousePressed == 1){
triangle.setPoint(me.getX(),me.getY(),index);
contentPane.validate();
contentPane.repaint();
}else if(mousePressed == 2){
index++;
triangle.setPoint(me.getX(), me.getY(), index);
contentPane.validate();
contentPane.repaint();
}else if(mousePressed == 3){
index++;
triangle.setPoint(me.getX(),me.getY(),index);
contentPane.validate();
contentPane.repaint();
mousePressed = 0;
index = 0;
}
System.out.println("Mouse Pressed: " + mousePressed + ", [" + triangle.getPoint(0) + "]," + "[" + triangle.getPoint(1) + "]" + "[" + triangle.getPoint(2) + "]");
}
#Override
public void mouseReleased(MouseEvent me) {
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
}
}
public class Triangle extends JPanel {
This class should not extend a JComponent like JPanel.
Instead it should provide a draw(Graphics) method that will paint the triangle when needed. Then store a list (e.g. ArrayList) of those Triangle objects and have it within the scope of a custom painted JPanel that paints them all at the same time. The custom painted panel should also return a sensible dimension for preferred size (that takes into account the bounds of the entire list of triangles to be painted).
I have tried a ton of different things to try to get the JLabel to show but I don't understand why it is not working. I have tried resizing it, though that is not what i want to do, I have tried other classes, but I would prefer to stick with this one, and it is starting to get really frustrating. If you have any ideas please help. But please try to keep them simple and explain very clearly as I am still quite new to java. I have only been going for about three or four months. Here is my code:
package com.thefallenpaladin;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* Created by darkp_000 on 11/4/2015.
*/
#SuppressWarnings("serial")
public class Game extends JPanel implements KeyListener,MouseListener {
public boolean mainMenu = true;
public int winWidth = 700; //Window Stats
public int winHeight = 600;
public int buttonOneX = 60; // Button Stats
public int buttonOneY = 240;
public int buttonOneW = 100;
public int buttonOneH = 75;
public boolean buttonOne = false;
public int mouseX; // not set because it is set in mouseClicked
public int mouseY;
public static void main(String[] args) {
Game game = new Game();
JFrame window = new JFrame("I hate this");
JLabel onePlayer = new JLabel();
onePlayer.setLocation(0,0/*game.buttonOneX + game.buttonOneX/2,game.buttonOneY + game.buttonOneY/2*/);
window.add(game);
window.setFocusable(true);
window.setResizable(false);
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setSize(700,600); //TODO
window.setVisible(true);
game.requestFocusInWindow();
game.add(onePlayer);
game.addKeyListener(game);
game.addMouseListener(game);
window.setLocationRelativeTo(null);
while(true) { // Main Game loop
onePlayer.setText("One Player");
game.repaint();
game.customUpdate();
}
}
public void customUpdate() {
if(mouseX > buttonOneX && mouseX < buttonOneX+buttonOneX && mouseY > buttonOneY && mouseY < buttonOneY+buttonOneY && mainMenu) {
buttonOne = true;
System.out.print("Starting Game");
}
}
public void paint(Graphics g) {
if(mainMenu) {
g.setColor(Color.CYAN); // Set main menu
g.fillRect(0,0,winWidth,winHeight);
g.setColor(Color.GREEN);
g.fillRect(buttonOneX,buttonOneY,buttonOneW,buttonOneH);
}
if(buttonOne) {
mainMenu = false;
g.setColor(Color.GREEN);
g.fillRect(0,0,winWidth,winHeight);
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
System.out.println(e);
}
public void keyReleased(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
// System.out.println(e);
mouseX = e.getX();
mouseY = e.getY();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
Okay so you've made a couple of basic mistakes...
First, JLabel onePlayer = new JLabel(); creates an empty label, with no size (0x0) and since labels are transparent by default, you'd not see it
Next, you've overridden paint of a top level container (JFrame), but failed to honor the paint chain effectively preventing any of the child components from ever getting painted
public void paint(Graphics g) {
if (mainMenu) {
g.setColor(Color.CYAN); // Set main menu
g.fillRect(0, 0, winWidth, winHeight);
g.setColor(Color.GREEN);
g.fillRect(buttonOneX, buttonOneY, buttonOneW, buttonOneH);
}
if (buttonOne) {
mainMenu = false;
g.setColor(Color.GREEN);
g.fillRect(0, 0, winWidth, winHeight);
}
}
So, if I remove your paint method and change JLabel onePlayer = new JLabel(); to JLabel onePlayer = new JLabel("I'm a label"); I get this output...
Also...
while (true) { // Main Game loop
onePlayer.setText("One Player");
game.repaint();
game.customUpdate();
}
has the potential to try screw up your program, you have no guarantee's in what thread your main method is been called and you should not make assumptions.
Start by creating a custom component, extending from something like JPanel and override it's paintComponent method, place your custom painting there. In fact, you should have a panel for each state of your game (menu, running, settings, etc).
Add these to your frame (probably using a CardLayout to enable you to easily switch between them)
Use either a Thread or Swing Timer as a main game loop, one which you create explicitly.
Have a look at Painting in AWT and Swing, Performing Custom Painting, How to Use CardLayout and How to use Swing Timers for some more details
As a "conceptual" example...
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class AwesomeGame {
public static void main(String[] args) {
new AwesomeGame();
}
public AwesomeGame() {
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 ContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface NavigationController {
public void letsPlay();
}
public class ContentPane extends JPanel implements NavigationController {
private CardLayout cardLayout;
private GamePane gamePane;
public ContentPane() {
cardLayout = new CardLayout();
setLayout(cardLayout);
add(new MenuPane(this), "TheMenu");
add((gamePane = new GamePane()), "TheGame");
cardLayout.show(this, "TheMenu");
}
#Override
public void letsPlay() {
cardLayout.show(this, "TheGame");
gamePane.play();
}
}
public class MenuPane extends JPanel {
public MenuPane(NavigationController navigationController) {
JLabel label = new JLabel("My Super Dupa Awesome Game!");
label.setFont(label.getFont().deriveFont(Font.BOLD, 48));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(label, gbc);
JButton play = new JButton("Play Now!");
play.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
navigationController.letsPlay();
}
});
add(play, gbc);
setBackground(Color.GREEN);
}
}
public class GamePane extends JPanel {
public GamePane() {
setBackground(Color.BLUE);
}
public void play() {
Timer timer = new Timer(500, new ActionListener() {
int count;
#Override
public void actionPerformed(ActionEvent e) {
count++;
if (count % 2 == 0) {
setForeground(Color.BLACK);
} else {
setForeground(Color.RED);
}
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
String text = "I bet you're blowen away by it's awesomness!";
FontMetrics fm = g2d.getFontMetrics();
int x = (getWidth() - fm.stringWidth(text)) / 2;
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(text, x, y);
g2d.dispose();
}
}
}
I'm not sure how I would fix the errors in my program and how I would highlight the option the user is hovering on. I want it to highlight the code for each position, i.e position 1 would be highlighted(as a different color) to start game,etc. and up/down would change position and I would change the position with up ,down, left, right. This is what I have so far. At the moment its bugged and when compiled with my window it comes out as:
Which works for the main game and altered for this titleboard, what am I doing wrong and how do I fix it?
TitleBoard class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
//sound + file opening
import java.io.*;
import javax.sound.sampled.*;
public class TitleBoard extends JPanel implements ActionListener{
private ArrayList<String> OptionList;
private Image background;
private ImageIcon bgImageIcon;
private String cheatString;
private int position;
private Timer timer;
public TitleBoard(){
setFocusable(true);
addKeyListener(new TAdapter());
bgImageIcon = new ImageIcon("");
background = bgImageIcon.getImage();
String[] options = {"Start Game","Options","Quit"};
OptionList = new ArrayList<String>();
optionSetup(options);
position = 1;
timer = new Timer(8, this);
timer.start();
/*
1 mod 3 =>1 highlight on start
2 mod 3 =>2 highlight on options
3 mod 3 =>0 highlight on quit
*/
try{
Font numFont = Font.createFont(Font.TRUETYPE_FONT,new File("TwistedStallions.ttf"));
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(numFont);
setFont(numFont.deriveFont(24f)); //adjusthislater
}catch(IOException|FontFormatException e){
e.printStackTrace();
}
}
private void optionSetup(String[] s){
for(int i=0; i<s.length;i++) {
OptionList.add(s[i]);
}
}
public void paint(Graphics g){
super.paint(g);
Graphics g2d = (Graphics2D)g;
g2d.drawImage(background,0,0,this);
for (int i=0;i<OptionList.size();i++){
g2d.drawString(OptionList.get(i),200,120+120*i);
}/*
g2d.drawString(OptionList.get(1),400,240);
g2d.drawString(OptionList.get(2),400,360);
//instructions on start screen maybe??
//800x500
//highlighting*/
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e){
repaint();
}
public class TAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_UP||
e.getKeyCode() == KeyEvent.VK_RIGHT){
position++;
}
if(e.getKeyCode() == KeyEvent.VK_DOWN||
e.getKeyCode() == KeyEvent.VK_LEFT){
position--;
}
}
}
}
Window Class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Window extends JFrame{
public Window(){
int width = 800, height = 600;
//TO DO: make a panel in TITLE MODE
///////////////////////////////////
//panel in GAME MODE.
add(new TitleBoard());
//set default close
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width,height);
//centers window
setLocationRelativeTo(null);
setTitle("Title");
setResizable(false);
setVisible(true);
}
public static void main(String[] args){
new Window();
}
}
There are any number of ways you might achieve this, for example, you could use some kind of delegation model.
That is, rather then trying to mange of each element in a single method (or methods), you could devise a delegate which provide a simple interface method that the paint method would call and it would know how to do the rest.
For example, Swing uses this type of concept with it's cell renderers for JList, JTable and JTree.
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MyAwesomeMenu {
public static void main(String[] args) {
new MyAwesomeMenu();
}
public MyAwesomeMenu() {
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 List<String> menuItems;
private String selectMenuItem;
private String focusedItem;
private MenuItemPainter painter;
private Map<String, Rectangle> menuBounds;
public TestPane() {
setBackground(Color.BLACK);
painter = new SimpleMenuItemPainter();
menuItems = new ArrayList<>(25);
menuItems.add("Start Game");
menuItems.add("Options");
menuItems.add("Exit");
selectMenuItem = menuItems.get(0);
MouseAdapter ma = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
String newItem = null;
for (String text : menuItems) {
Rectangle bounds = menuBounds.get(text);
if (bounds.contains(e.getPoint())) {
newItem = text;
break;
}
}
if (newItem != null && !newItem.equals(selectMenuItem)) {
selectMenuItem = newItem;
repaint();
}
}
#Override
public void mouseMoved(MouseEvent e) {
focusedItem = null;
for (String text : menuItems) {
Rectangle bounds = menuBounds.get(text);
if (bounds.contains(e.getPoint())) {
focusedItem = text;
repaint();
break;
}
}
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "arrowDown");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "arrowUp");
am.put("arrowDown", new MenuAction(1));
am.put("arrowUp", new MenuAction(-1));
}
#Override
public void invalidate() {
menuBounds = null;
super.invalidate();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (menuBounds == null) {
menuBounds = new HashMap<>(menuItems.size());
int width = 0;
int height = 0;
for (String text : menuItems) {
Dimension dim = painter.getPreferredSize(g2d, text);
width = Math.max(width, dim.width);
height = Math.max(height, dim.height);
}
int x = (getWidth() - (width + 10)) / 2;
int totalHeight = (height + 10) * menuItems.size();
totalHeight += 5 * (menuItems.size() - 1);
int y = (getHeight() - totalHeight) / 2;
for (String text : menuItems) {
menuBounds.put(text, new Rectangle(x, y, width + 10, height + 10));
y += height + 10 + 5;
}
}
for (String text : menuItems) {
Rectangle bounds = menuBounds.get(text);
boolean isSelected = text.equals(selectMenuItem);
boolean isFocused = text.equals(focusedItem);
painter.paint(g2d, text, bounds, isSelected, isFocused);
}
g2d.dispose();
}
public class MenuAction extends AbstractAction {
private final int delta;
public MenuAction(int delta) {
this.delta = delta;
}
#Override
public void actionPerformed(ActionEvent e) {
int index = menuItems.indexOf(selectMenuItem);
if (index < 0) {
selectMenuItem = menuItems.get(0);
}
index += delta;
if (index < 0) {
selectMenuItem = menuItems.get(menuItems.size() - 1);
} else if (index >= menuItems.size()) {
selectMenuItem = menuItems.get(0);
} else {
selectMenuItem = menuItems.get(index);
}
repaint();
}
}
}
public interface MenuItemPainter {
public void paint(Graphics2D g2d, String text, Rectangle bounds, boolean isSelected, boolean isFocused);
public Dimension getPreferredSize(Graphics2D g2d, String text);
}
public class SimpleMenuItemPainter implements MenuItemPainter {
public Dimension getPreferredSize(Graphics2D g2d, String text) {
return g2d.getFontMetrics().getStringBounds(text, g2d).getBounds().getSize();
}
#Override
public void paint(Graphics2D g2d, String text, Rectangle bounds, boolean isSelected, boolean isFocused) {
FontMetrics fm = g2d.getFontMetrics();
if (isSelected) {
paintBackground(g2d, bounds, Color.BLUE, Color.WHITE);
} else if (isFocused) {
paintBackground(g2d, bounds, Color.MAGENTA, Color.BLACK);
} else {
paintBackground(g2d, bounds, Color.DARK_GRAY, Color.LIGHT_GRAY);
}
int x = bounds.x + ((bounds.width - fm.stringWidth(text)) / 2);
int y = bounds.y + ((bounds.height - fm.getHeight()) / 2) + fm.getAscent();
g2d.setColor(isSelected ? Color.WHITE : Color.LIGHT_GRAY);
g2d.drawString(text, x, y);
}
protected void paintBackground(Graphics2D g2d, Rectangle bounds, Color background, Color foreground) {
g2d.setColor(background);
g2d.fill(bounds);
g2d.setColor(foreground);
g2d.draw(bounds);
}
}
}
For here, you could add ActionListener
When a GUI needs a button, use a JButton! The JButton API allows the possibility to add icons for many different circumstances. This example shows different icons for the standard icon, the hover icon, and the pressed icon. Your GUI would obviously use icons with text on them for the required effect.
The icons are pulled directly (hot-linked) from Example images for code and mark-up Q&As.
Standard
Hover over triangle
Press triangle
Code
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;
public class IconHoverFocusIndication {
// the GUI as seen by the user (without frame)
// swap the 1 and 0 for single column
JPanel gui = new JPanel(new GridLayout(1,0,50,50));
public static final int GREEN = 0, YELLOW = 1, RED = 2;
String[][] urls = {
{
"http://i.stack.imgur.com/T5uTa.png",
"http://i.stack.imgur.com/IHARa.png",
"http://i.stack.imgur.com/wCF8S.png"
},
{
"http://i.stack.imgur.com/gYxHm.png",
"http://i.stack.imgur.com/8BGfi.png",
"http://i.stack.imgur.com/5v2TX.png"
},
{
"http://i.stack.imgur.com/1lgtq.png",
"http://i.stack.imgur.com/6ZXhi.png",
"http://i.stack.imgur.com/F0JHK.png"
}
};
IconHoverFocusIndication() throws Exception {
// adjust to requirement..
gui.setBorder(new EmptyBorder(15, 30, 15, 30));
gui.setBackground(Color.BLACK);
Insets zeroMargin = new Insets(0,0,0,0);
for (int ii = 0; ii < 3; ii++) {
JButton b = new JButton();
b.setBorderPainted(false);
b.setMargin(zeroMargin);
b.setContentAreaFilled(false);
gui.add(b);
URL url1 = new URL(urls[ii][GREEN]);
BufferedImage bi1 = ImageIO.read(url1);
b.setIcon(new ImageIcon(bi1));
URL url2 = new URL(urls[ii][YELLOW]);
BufferedImage bi2 = ImageIO.read(url2);
b.setRolloverIcon(new ImageIcon(bi2));
URL url3 = new URL(urls[ii][RED]);
BufferedImage bi3 = ImageIO.read(url3);
b.setPressedIcon(new ImageIcon(bi3));
}
}
public JComponent getGUI() {
return gui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
IconHoverFocusIndication ihfi =
new IconHoverFocusIndication();
JFrame f = new JFrame("Button Icons");
f.add(ihfi.getGUI());
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See https://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
I need to have a program that when I click on the card it will flip to the back side of the card and when I click on it again it will show the face again. Please Help, I have it to when I click the card it will show the back of it but how do I get it to show the front again?
import java.awt.Button;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.JApplet;
public class DealCard extends JApplet implements ActionListener, MouseListener {
Random gen = new Random();
Button dealButton = new Button("Deal");
int card1 = 0;
Image[] card = new Image[53];
Image[] back= new Image[1];
int number = 0;
public void init() {
setSize(200, 200);
setLayout(null);
for (int i = 0; i < 53; i++) {
card[i] = getImage(getCodeBase(), "card" + (i + 1) + ".gif");
}
dealButton.setBounds(100, 200, 80, 30);
add(dealButton);
dealButton.addActionListener(this);
dealButton.setEnabled(true);
addMouseListener(this);
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(card[card1], 100, 100, 82, 82, this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == dealButton) {
card1 = gen.nextInt(52);
}
repaint();
}
public void mouseClicked(MouseEvent e){
int x = e.getX();
int y = e.getY();
if(x > 100 && x < (100+82) && y > 100 && y < (100+82)){
card1 = 52;
System.out.println(card1);
repaint();
e.consume();
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}
You need a boolean value to state whether the card is facing up or not.
Then add a condition to your draw statement that checks if the card is facing up or not.
Hope that helps.
You should also add a back card image, which does not need to be an array as it is just one.
Image back= new Image();
Or alternatively make card[0] your back card Image.
I've written this simple program which displays key presses, draws the phrase "Hello World," where one's cursor moves (with a trail mode when clicked) and also cycles through the Colors in which "Hello World," is picked out when the mouse wheel is scrolled. However there is a problem with this: When the mouse wheel scrolls the entire window goes blank (showing the default grey color from when you first make a component visible) and will then be redrawn with the color change (a very small change only to the "Hello World," which doesn't seem to require that the whole frame be redrawn.
The time for which the blankness occurs seems to correlate with the force with which the mouse wheel is scrolled, if I scroll very lightly there is only a very tiny moment where everything is not displayed, however scrolling very hard can make the window go blank for 2-3 seconds.
I've tried double buffering - thinking that this might be some sort of screen flicker - but it has made no change and I'm at a loss as to what could be causing this weird effect. It's as if the frame image is loading while the Wheel motion event is happening. (Is there perhaps a way to exit from the wheel event immediately so as to reduce loading time? (This is just my guesses as to possible solutions)).
The code is below. Any ideas would be greatly appreciated.
package keymouse;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferStrategy;
import java.util.LinkedList;
import javax.swing.JFrame;
public class KeyMouse implements KeyListener,
MouseMotionListener, MouseListener, MouseWheelListener, Runnable {
boolean trailMode = false;
boolean exists = false;
display window;
LinkedList wordList;
LinkedList trailList;
LinkedList colorList;
Point mousePoint;
int TRAIL_SIZE = 10;
boolean init = true;
int FONT_SIZE = 32;
int mouseY;
int mouseX;
int y;
int colorCount = 0;
public static void main(String[] args) {
KeyMouse k = new KeyMouse();
k.run();
}
public KeyMouse() {
window = new display();
window.addKeyListener(this);
window.addMouseMotionListener(this);
window.addMouseListener(this);
window.addMouseWheelListener(this);
window.setBackground(Color.WHITE);
window.setForeground(Color.BLACK);
wordList = new LinkedList();
trailList = new LinkedList();
colorList = new LinkedList();
colorList.add(Color.BLACK);
colorList.add(Color.BLUE);
colorList.add(Color.YELLOW);
colorList.add(Color.GREEN);
colorList.add(Color.PINK);
}
#Override
public void keyTyped(KeyEvent e) {
// do nothing
}
#Override
public void keyPressed(KeyEvent e) {
int keyCode;
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
stop();
}
keyCode = e.getKeyCode();
addMessage("Pressed:" + e.getKeyText(keyCode));
}
#Override
public void keyReleased(KeyEvent e) {
//do nothing
}
#Override
public void mouseDragged(MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
addLocation(p);
}
#Override
public void mouseMoved(MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
addLocation(p);
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
trailMode = true;
}
#Override
public void mouseReleased(MouseEvent e) {
trailMode = false;
}
#Override
public void mouseEntered(MouseEvent e) {
//do nothing
}
#Override
public void mouseExited(MouseEvent e) {
//do nothing
}
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
System.out.println(e.getWheelRotation());
colorCount++;
if (colorCount > 4) {
colorCount = 0;
}
window.setForeground((Color) colorList.get(colorCount));
}
#Override
public void run() {
window.createBufferStrategy(2);
BufferStrategy strategy = window.getBufferStrategy();
while (true) {
draw(strategy.getDrawGraphics());
strategy.show();
try {
Thread.sleep(20);
} catch (Exception ex) {
}
}
}
public void draw(Graphics g) {
//draw background
g.setColor(window.getBackground());
g.fillRect(0, 0, window.getWidth(), window.getHeight());
//draw Text
g.setColor(window.getForeground());
g.setFont(new Font("sansserif", Font.BOLD, 32));
int count = trailList.size();
if (trailList.size() > 1 && trailMode == false) {
count = 1;
}
if (exists == true) {
for (int i = 0; i < count; i++) {
Point p = (Point) trailList.get(i);
g.drawString("Hello World", p.x, p.y);
}
}
g.setColor(Color.BLACK);
y = 56;
for (int i = 0; i < wordList.size(); i++) {
String word = (String) wordList.get(i);
g.drawString((String) wordList.get(i), 100, y);
y += 32;
}
}
public void addMessage(String message) {
if (y >= window.getHeight()) {
wordList.remove(0);
}
wordList.add(message);
}
public void addLocation(Point h) {
exists = true;
trailList.addFirst(h);
if (trailList.size() > TRAIL_SIZE) {
trailList.removeLast();
}
}
public void printMessages() {
for (int i = 0; i < wordList.size(); i++) {
System.out.println(wordList.get(i));
}
}
private void stop() {
System.exit(0);
}
Absent a complete example, I can't reproduce the effect you describe. You might compare your code to this example, which exhibits no apparent blanking.
In general,
JPanel is double buffered by default; it's unusual to need a different buffer strategy.
AnimationTest illustrates a Swing Timer and how to display your average paint period.
MouseAdapter is convenient for overriding a small number of methods.
When possible, use generic parameters for type safety.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* #see https://stackoverflow.com/a/10970892/230513
*/
public class ColorWheel extends JPanel {
private static final int N = 32;
private final Queue<Color> clut = new LinkedList<Color>();
private final JLabel label = new JLabel();
public ColorWheel() {
for (int i = 0; i < N; i++) {
clut.add(Color.getHSBColor((float) i / N, 1, 1));
}
this.setBackground(clut.peek());
label.setText(getBackground().toString());
this.add(label);
this.addMouseWheelListener(new MouseAdapter() {
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
setBackground(clut.peek());
label.setText(getBackground().toString());
clut.add(clut.remove());
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
private void display() {
JFrame f = new JFrame("ColorWheel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ColorWheel().display();
}
});
}
}