I am trying to simulate a traffic light with radio buttons. No matter where I put the call to repaint(), it does not seem to call the paintComponent method. Any help would be appreciated. Here is my code. Sorry if this is kind of long.
package trafficlight;
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.event.*;
public class Frame extends JFrame{
Drawing ob = new Drawing();
private JPanel buttonPanel;
private JRadioButton red;
private JRadioButton yellow;
private JRadioButton green;
public Frame(String title, int width, int height) {
super(title);
setSize(width, height);
buttonPanel = new JPanel();
//creating JFrame components
red = new JRadioButton("Red");
yellow = new JRadioButton("Yellow");
green = new JRadioButton("Green");
buttonPanel.add(red);
buttonPanel.add(yellow);
buttonPanel.add(green);
//JRadioButton group allows only one button to be selected at a time
ButtonGroup group = new ButtonGroup();
group.add(red);
group.add(yellow);
group.add(green);
//adding components to frame
add(buttonPanel, BorderLayout.SOUTH);
//Adding action listeners
red.addActionListener(new Listener());
yellow.addActionListener(new Listener());
green.addActionListener(new Listener());
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//Listener class to handle action events
private class Listener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
if(red.isSelected()){
ob.setRed(true);
ob.setYellow(false);
ob.setGreen(false);
ob.repaint();
}
else if(yellow.isSelected()){
ob.setYellow(true);
ob.setGreen(false);
ob.setRed(false);
ob.repaint();
}
else if(green.isSelected()){
ob.setGreen(true);
ob.setYellow(false);
ob.setRed(false);
ob.repaint();
}
}
}
}
Here is my seconds class
package trafficlight;
import java.awt.*;
import javax.swing.*;
public class Drawing extends JPanel{
private boolean red = false;
private boolean yellow = false;
private boolean green = false;
public void setRed(boolean clicked){
this.red = clicked;
}
public void setYellow(boolean clicked){
this.yellow = clicked;
}
public void setGreen(boolean clicked){
this.green = clicked;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawRect(85, 20, 60, 110);
if(!red){
g.setColor(Color.black);
g.drawOval(100, 25, 30, 30);
}
else{
g.setColor(Color.red);
g.fillOval(100, 25, 30, 30);
}
if(!yellow){
g.setColor(Color.black);
g.drawOval(100, 60, 30, 30);
}
else{
g.setColor(Color.yellow);
g.fillOval(100, 60, 30, 30);
}
if(!green){
g.setColor(Color.black);
g.drawOval(100, 95, 30, 30);
}
else{
g.setColor(Color.green);
g.fillOval(100, 95, 30, 30);
}
}
}
And here's the main method
package trafficlight;
public class TrafficLight {
public static void main(String[] args) {
Frame test = new Frame("TrafficLight", 250, 250);
test.add(new Drawing());
}
}
Some improvements for your code
Don't inherit from JFrame. You don't add any value to this class (composition over inheritance)
Your ActionListener doesn't need to be a named class because it hasn't got any state
No need for a field in your case
Use the Color constants with the UPPERCASE i.e. Color.BLACK
Enqueue Swing application in the EDT
Use more descriptive names for classes and variables
Then your program may look like this:
public class TrafficLightUI {
public TrafficLightUI(String title, int width, int height) {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width, height);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
JRadioButton redRadioButton = new JRadioButton("Red");
JRadioButton yellowRadioButton = new JRadioButton("Yellow");
JRadioButton greenRadioButton = new JRadioButton("Green");
buttonPanel.add(redRadioButton);
buttonPanel.add(yellowRadioButton);
buttonPanel.add(greenRadioButton);
//JRadioButton group allows only one button to be selected at a time
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(redRadioButton);
buttonGroup.add(yellowRadioButton);
buttonGroup.add(greenRadioButton);
TrafficLightPanel trafficLight = new TrafficLightPanel();
//adding components to frame
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
mainPanel.add(trafficLight, BorderLayout.CENTER);
//Adding action listeners
redRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(true, false, false, trafficLight);
}
});
yellowRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(false, true, false, trafficLight);
}
});
greenRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(false, false, true, trafficLight);
}
});
frame.add(mainPanel);
frame.setVisible(true);
}
private void setTrafficLight(boolean red, boolean yellow, boolean green, TrafficLightPanel trafficLight) {
trafficLight.setGreen(green);
trafficLight.setYellow(yellow);
trafficLight.setRed(red);
trafficLight.repaint();
}
}
TrafficLightPanel
public class TrafficLightPanel extends JPanel {
private static final long serialVersionUID = 1L;
private boolean red = false;
private boolean yellow = false;
private boolean green = false;
public void setRed(boolean isRed) {
this.red = isRed;
}
public void setYellow(boolean isYellow) {
this.yellow = isYellow;
}
public void setGreen(boolean isGreen) {
this.green = isGreen;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawRect(85, 20, 60, 110);
if (!red) {
g.setColor(Color.BLACK);
g.drawOval(100, 25, 30, 30);
} else {
g.setColor(Color.RED);
g.fillOval(100, 25, 30, 30);
}
if (!yellow) {
g.setColor(Color.BLACK);
g.drawOval(100, 60, 30, 30);
} else {
g.setColor(Color.YELLOW);
g.fillOval(100, 60, 30, 30);
}
if (!green) {
g.setColor(Color.BLACK);
g.drawOval(100, 95, 30, 30);
} else {
g.setColor(Color.GREEN);
g.fillOval(100, 95, 30, 30);
}
}
}
Main
public class TrafficLight {
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TrafficLightUI("TrafficLight", 250, 250);
}
});
}
}
Related
I made the Card Layout Working completely fine but what happened now is I added a keylistener to the object character which is a JLabel so whenever the person presses up the character should move up but it does absolutely nothing!
I also tried replacing it with a button which moves it when clicked and it worked completely fine. Also I tried changing the event meaning I changed that if they press up then the image of the town map would change but still no effect so it seems there is something wrong with my KeyListener
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.*;
import javax.swing.*;
#SuppressWarnings({ "unused", "serial" })
public class FinalBlowzXC extends JFrame implements KeyListener{
public static JPanel game=new JPanel();
public static JPanel mainmenu=new JPanel(null);
public static JPanel loginpanel=new JPanel(null);
public static JPanel tutorial=new JPanel(null);
public static JPanel registration=new JPanel(null);
public static JPanel town_map=new JPanel(null);
public JTextField username= new JTextField("Username");
public JTextField password=new JTextField("Password");
public JLabel bglogin=new JLabel();
public JLabel character=new JLabel();
public JButton log_in=new JButton();
public JButton register=new JButton();
CardLayout page= new CardLayout();
public String level="";
public int charx=350;
public int chary=435;
public static void main(String []args)
{
new FinalBlowzXC().setVisible(true);
}
public FinalBlowzXC()
{
super("Final Blowz Xchanged");
setSize(640,510);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
game.setLayout(page);
game.add(mainmenu, "1");
game.add(loginpanel, "2");
game.add(tutorial, "3");
game.add(registration, "4");
game.add(town_map, "5");
add(game);
opening();
}
public void opening()
{
page.show(game, "1");
JLabel bgmainmenu;
JButton start;
JButton exit;
bgmainmenu = new JLabel();
start = new JButton();
exit = new JButton();
bgmainmenu.setIcon(new ImageIcon(getClass().getResource("/FF-XV.jpg")));
bgmainmenu.setBounds(0,0,640,480);
mainmenu.add(bgmainmenu);
mainmenu.add(start);
start.setBounds(280, 360, 70, 20);
start.setBorder(null);
start.setBorderPainted(false);
start.setContentAreaFilled(false);
start.setOpaque(false);
start.addActionListener(new Start());
exit.setBounds(280, 385, 70, 20);
mainmenu.add(exit);
exit.setBorder(null);
exit.setBorderPainted(false);
exit.setContentAreaFilled(false);
exit.setOpaque(false);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
}
class Start implements ActionListener{
public void actionPerformed(ActionEvent e) {
login();
}
}
public void login()
{
page.show(game, "2");
bglogin.setIcon(new ImageIcon(getClass().getResource("/FF-XV Login.jpg")));
bglogin.setBounds(0, 0, 640, 480);
username.setBounds(300, 285, 85, 15);
username.setBorder(null);
username.setForeground(Color.WHITE);
username.setOpaque(false);
password.setBounds(300, 310, 85, 20);
password.setBorder(null);
password.setForeground(Color.WHITE);
password.setOpaque(false);
log_in.setBounds(280, 335, 50, 45);
log_in.setBorder(null);
log_in.setBorderPainted(false);
log_in.setContentAreaFilled(false);
log_in.setOpaque(false);
log_in.addActionListener(new Log_in());
register.setBounds(335, 335, 55, 45);
register.setBorder(null);
register.setBorderPainted(false);
register.setContentAreaFilled(false);
register.setOpaque(false);
register.addActionListener(new Register());
loginpanel.add(username);
loginpanel.add(password);
loginpanel.add(bglogin);
loginpanel.add(log_in);
loginpanel.add(register);
}
class Log_in implements ActionListener{
public void actionPerformed(ActionEvent e)
{
Tutorial();
}
}
class Register implements ActionListener{
public void actionPerformed(ActionEvent e)
{
page.show(game, "4");
}
}
public void Tutorial()
{
page.show(game, "3");
JLabel bgtutorial=new JLabel();
JLabel animeforward=new JLabel();
JLabel animeright=new JLabel();
JLabel animeleft=new JLabel();
JButton next=new JButton();
JLabel animebackward=new JLabel();
bgtutorial.setIcon(new ImageIcon(getClass().getResource("/FF-XV Tutorial.jpg")));
bgtutorial.setBounds(0, 0, 640, 480);
animeforward.setIcon(new ImageIcon(getClass().getResource("walkanimofficialfront.gif")));
animeforward.setBounds(115, 230, 30, 30);
animeright.setIcon(new ImageIcon(getClass().getResource("walkanimofficialright.gif")));
animeright.setBounds(190, 315, 30, 30);
animeleft.setIcon(new ImageIcon(getClass().getResource("walkanimofficialleft.gif")));
animeleft.setBounds(45, 315, 30, 30);
animebackward.setIcon(new ImageIcon(getClass().getResource("walkanimofficialback.gif")));
animebackward.setBounds(115, 405, 30, 30);
next.setBounds(530, 430, 100, 30);
next.setBorder(null);
next.setBorderPainted(false);
next.setContentAreaFilled(false);
next.setOpaque(false);
next.addActionListener(new Next());
tutorial.add(next);
tutorial.add(animeright);
tutorial.add(animeleft);
tutorial.add(animebackward);
tutorial.add(animeforward);
tutorial.add(bgtutorial);
}
class Next implements ActionListener{
public void actionPerformed(ActionEvent e)
{
town();
}
}
public void town()
{
page.show(game, "5");
JLabel map=new JLabel();
map.setIcon(new ImageIcon(getClass().getResource("/FF-XV Town.jpg")));
map.setBounds(0, 0, 640, 480);
character.setIcon(new ImageIcon(getClass().getResource("standfront.png")));
character.setBounds(charx, chary, 30, 35);
town_map.add(character);
town_map.add(map);
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_UP)
{
character.setIcon(new ImageIcon(getClass().getResource("walkanimofficialfront.gif")));
character.setLocation(character.getX(), character.getY()+5);
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT)
{
character.setIcon(new ImageIcon(getClass().getResource("walkanimofficialright.gif")));
character.setLocation(character.getX()+5, character.getY());
}
if(e.getKeyCode()==KeyEvent.VK_LEFT)
{
character.setIcon(new ImageIcon(getClass().getResource("walkanimofficialleft.gif")));
character.setLocation(character.getX()-5, character.getY()+5);
}
if(e.getKeyCode()==KeyEvent.VK_DOWN)
{
character.setIcon(new ImageIcon(getClass().getResource("walkanimofficialback.gif")));
character.setLocation(character.getX(), character.getY()-5);
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
Add following code in your programme.
public static JPanel mainmenu = new JPanel();
public static JPanel loginpanel = new JPanel();
or initialize mainmenu & loginpanel before adding them into the game panel.
when you call game.add(loginPanel, "2") loginPanel is null
I am trying to create a hangman game with a button for each letter of the alphabet. I have done this the hard way, using absolute positioning and multiple actionlisteners. Is there any way I can do both with a for loop?
Also, how can I implement my hangman using a polymorphic array? The way I have it now, I will use an if statement for each of the limbs. I'd wrather create the man on his own panel, then set the visibility for each limg to true as the use fails at guessing.
Any help is appreciated.
public class HangmanGui extends JFrame{
private JLabel headerLabel;
private JPanel man;
private Graphics gobj;
private JButton aButton ;
private JButton bButton ;
private JButton cButton ;
private JButton dButton ;
private JButton eButton ;
private JButton fButton ;
private JButton gButton ;
private JButton hButton ;
private JButton iButton ;
private JButton jButton ;
private JButton kButton ;
private JButton lButton ;
private JButton mButton ;
private JButton nButton ;
private JButton oButton ;
private JButton pButton ;
private JButton qButton ;
private JButton rButton ;
private JButton sButton ;
private JButton tButton ;
private JButton uButton ;
private JButton vButton ;
private JButton wButton ;
private JButton xButton ;
private JButton yButton ;
private JButton zButton ;
private JButton newWButton ;
private JButton showWButton ;
private JButton quitButton ;
private JButton startButton ;
private JLabel blankWord;
private JLabel titleWord;
private JFrame frame;
private JPanel hangman;
private FlowLayout layout;
private Container container;
/*
public static void main (String[] args){
GUITest gui = new GUITest();
gui.setSize(800,900);
gui.setVisible(true);
}
*/
//
// public GUITest()
// {
// }
public HangmanGui(){
buildGui();
}
public void buildGui(){
frame = new JFrame();
frame.getContentPane().setBackground(Color.WHITE);
frame.setBackground(Color.WHITE);
frame.setBounds(100, 100, 450, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
Font lblFont= new Font("Serif", Font.BOLD, 30);
JLabel[] uscore = new JLabel[15];
Man man = new Man();
titleWord = new JLabel("A Game of Hangman.");
titleWord.setBounds(260,10,500,150);
titleWord.setFont(lblFont);
add(titleWord);
// add(blankWord);
//frame.add(man);
this.add(man);
man.setBounds(100,100,400,400);
JPanel panel = new JPanel();
panel.setBounds(6, 232, 400, 400);
frame.getContentPane().add(panel);
layout = new FlowLayout();
container = getContentPane();
setLayout(null);
aButton = new JButton("A");
add(aButton);
aButton.setBounds(30, 520, 50, 29);
aButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
bButton = new JButton("B");
add(bButton);
bButton.setBounds(80, 520, 50, 29);
bButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
cButton = new JButton("C");
add(cButton);
cButton.setBounds(130, 520, 50, 29);
cButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
dButton = new JButton("D");
add(dButton);
dButton.setBounds(180, 520, 50, 29);
dButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
eButton = new JButton("E");
add(eButton);
eButton.setBounds(230, 520, 50, 29);
eButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
fButton = new JButton("F");
add(fButton);
fButton.setBounds(280, 520, 50, 29);
fButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
gButton = new JButton("G");
add(gButton);
gButton.setBounds(330, 520, 50, 29);
gButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
hButton = new JButton("H");
add(hButton);
hButton.setBounds(380, 520, 50, 29);
hButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
iButton = new JButton("I");
add(iButton);
iButton.setBounds(430, 520, 50, 29);
iButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
jButton = new JButton("J");
add(jButton);
jButton.setBounds(480, 520, 50, 29);
jButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
kButton = new JButton("K");
add(kButton);
kButton.setBounds(530, 520, 50, 29);
kButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
lButton = new JButton("L");
add(lButton);
lButton.setBounds(580, 520, 50, 29);
lButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
mButton = new JButton("M");
add(mButton);
mButton.setBounds(630, 520, 50, 29);
mButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
nButton = new JButton("N");
add(nButton);
nButton.setBounds(680, 520, 50, 29);
nButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
oButton = new JButton("O");
add(oButton);
oButton.setBounds(30, 550, 50, 29);
oButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
pButton = new JButton("P");
add(pButton);
pButton.setBounds(80, 550, 50, 29);
pButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
qButton = new JButton("Q");
add(qButton);
qButton.setBounds(130, 550, 50, 29);
qButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
rButton = new JButton("R");
add(rButton);
rButton.setBounds(180, 550, 50, 29);
rButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
sButton = new JButton("S");
add(sButton);
sButton.setBounds(230, 550, 50, 29);
sButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
tButton = new JButton("T");
add(tButton);
tButton.setBounds(280, 550, 50, 29);
tButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
uButton = new JButton("U");
add(uButton);
uButton.setBounds(330, 550, 50, 29);
uButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
vButton = new JButton("V");
add(vButton);
vButton.setBounds(380, 550, 50, 29);
vButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
wButton = new JButton("W");
add(wButton);
wButton.setBounds(430, 550, 50, 29);
wButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
xButton = new JButton("X");
add(xButton);
xButton.setBounds(480, 550, 50, 29);
xButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
yButton = new JButton("Y");
add(yButton);
yButton.setBounds(530, 550, 50, 29);
yButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
zButton = new JButton("Z");
add(zButton);
zButton.setBounds(580, 550, 50, 29);
zButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
startButton = new JButton("Start Game");
add(startButton);
startButton.setBounds(100, 700, 120, 29);
startButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
newWButton = new JButton("New Word");
add(newWButton);
newWButton.setBounds(250, 700, 120, 29);
newWButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
showWButton = new JButton("Show Word");
add(showWButton);
showWButton.setBounds(400, 700, 120, 29);
showWButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
quitButton = new JButton("Quit Game");
add(quitButton);
quitButton.setBounds(550, 700, 120, 29);
quitButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
}
}
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JPanel;
public class Man extends JPanel {
protected void paintComponent(Graphics g ){
super.paintComponent(g);
//gallows
g.fillRect(10, 250, 150, 20);
g.fillRect(40,70,10,200);
g.fillRect(40,70,60,10);
g.setColor(Color.yellow);
g.fillRect(95,70,5,25);
//head
g.setColor(Color.black);
g.drawOval(82,95,30,30);
//body
g.drawLine(97,125,97,150);
//left leg
g.drawLine(97,150,117,183);
//right leg
g.drawLine(97,150,77,183);
// right arm
g.drawLine(97,125,117,135);
//left arm
g.drawLine(97,125,77,135);
}
}
Use a layout manager to manage the sizing of your buttons, don't use setBounds(). You currently create one but don't set it and so its not used.
layout = new FlowLayout();
setLayout(null); // Why set null and not layout
Set the layout correctly and then you could can use a char in your for loop like
for(char c = 'A'; c <= 'Z'; c++)
{
JButton button = new JButton("" + c);
// add action listener also
add(button); // adding will add it using the layout manager
}
You can learn more about layout managers here.
You could try something like this:
// create a JPanel to hold the buttons that uses a GridLayout with 3 rows
JPanel buttonPanel = new JPanel(new GridLayout(3, ));
for (int i = 0; i < 26; ++i)
{
wButton = new JButton('A' + i);
buttonPanel.add(wButton);
// wButton.setBounds(30 + i * 50, 550, 50, 29); // avoid this
wButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
}
// here add the buttonPanel to the main GUI
To break this down:
1) We use a for loop to go thru the 26 letters of the alphabet.
2) We create a button with the title being the letter. Because characters are actually just integers, adding 1 to 'A' yields 'B'. So, we can use 'A'+i as a little trick. Also, you could use an array of all the letters instead and do something like letter[i] there.
3) Avoid use of setBounds but rather use the layout managers to more easily and simply place and size the buttons.
Disclaimer: I haven't actually tested this, it's just something to get you on the right track.
Suggestions:
Yes, use an array or a collection such as either a simple array of JButton or a List<JButton> or its concrete implementation, an ArrayList<JButton>
Yes, create your letter JButtons in a for loop as many have suggested.
But don't create your special buttons there, buttons such as your reset button or your exit button.
Create one AbstractAction or ActionListener class for all the letter buttons to share and a unique AbstractAction or ActionListener class for each special JButton
Use layout managers, but not just one -- nest them. For instance, the overall GUI can use a BorderLayout with the drawing held BorderLayout.CENTER and the buttons in the SOUTH or PAGE_END position, the JPanels that hold your buttons could be held in a BoxLayout using JPanel, the letter buttons in a GridLayout using JPanel and the same for the specialty buttons.
Use a separate JPanel for drawing the hangman image. Keep its logic separate from everything else. All it cares about is the number of wrong letters guessed, and then it should draw the appropriate images depending on this value. So I'd give it a public method for incrementing this number as well as a public method for resetting the number and its drawing.
For instance
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class LayoutFoo extends JPanel {
// using a List of JButtons to hold my collection
private List<JButton> letterButtons = new ArrayList<>();
private DrawingPanel drawingPanel = new DrawingPanel();
public LayoutFoo() {
JPanel letterButtonPanel = new JPanel(new GridLayout(3, 0, 3, 3));
letterButtonPanel.setBorder(BorderFactory.createTitledBorder("Letters"));
ButtonListener buttonListener = new ButtonListener();
for (char c = 'A'; c <= 'Z'; c++) {
String text = String.valueOf(c);
JButton button = new JButton(text);
button.addActionListener(buttonListener);
letterButtons.add(button); // add JButton to List<JButton>
letterButtonPanel.add(button); // and add to GridLayout-using JPanel
}
// JPanel to hold non-letter JButtons
JPanel specialBtnsPanel = new JPanel(new GridLayout(1, 0, 3, 3));
specialBtnsPanel.add(new JButton(new ResetAction("Reset", KeyEvent.VK_R)));
specialBtnsPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
// JPanel to hold non-drawing JPanels. It uses BoxLayout
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.PAGE_AXIS));
bottomPanel.add(letterButtonPanel);
bottomPanel.add(specialBtnsPanel);
// set layout and border of main JPanel and add other JPanels to it
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
setLayout(new BorderLayout(3, 3));
add(drawingPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed: " + e.getActionCommand());
((AbstractButton) e.getSource()).setEnabled(false);
}
}
private class ResetAction extends AbstractAction {
public ResetAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
for (JButton button : letterButtons) {
button.setEnabled(true);
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component component = (Component) e.getSource();
Window win = SwingUtilities.getWindowAncestor(component);
win.dispose();
}
}
private static void createAndShowGui() {
LayoutFoo mainPanel = new LayoutFoo();
JFrame frame = new JFrame("LayoutFoo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class DrawingPanel extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private int wrongLetterCount = 0;
public DrawingPanel() {
setBorder(BorderFactory.createTitledBorder("Hang Man"));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// TODO: draw hangman here based on wrong letter count!
}
public void incrementWrongLetterCount() {
wrongLetterCount++;
repaint();
}
public void reset() {
wrongLetterCount = 0;
repaint();
}
}
I have small issue. In main i have such thing:
JTabbedPane tabsPane = new JTabbedPane();
add(tabsPane,BorderLayout.CENTER);
JPanel tab1Panel = new JPanel();
JPanel tab2Panel = new JPanel();
//DrawingWindow drawingWindow= new DrawingWindow();
//add(drawingWindow);
tabsPane.addTab("Animacja", tab1Panel);
tabsPane.addTab("Wykresy", tab2Panel);
JButton test = new JButton("Press");
tab2Panel.add(test);
Drawing Window class
public class DrawingWindow extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
public static Balls balls=new Balls();
public DrawingWindow() {
MakeBall();
}
private void MakeBall()
{
balls=new Balls(10,205,5,10);
}
public void paint(Graphics gg){
super.paint(gg);
Graphics2D g = (Graphics2D) gg;
g.setColor(Color.GRAY);
g.fillRect(0,70,515,410);
g.setColor(Color.WHITE);
g.drawLine(10, 285, 57, 265);
g.drawLine(10, 285, 57, 305);
g.drawLine(515, 285, 458, 265);
g.drawLine(515, 285, 458, 305);
for(int ii=0;ii<Parameters.numberOfCovers;ii++)
{
if(Parameters.whatCovers[ii]==0)
{
g.setColor(Color.YELLOW);
g.fillRect(132+(57*2*ii), 205, 29+2*Parameters.cmCovers[ii], 150 );
}
if(Parameters.whatCovers[ii]==1)
{
g.setColor(Color.GREEN);
g.fillRect(132+(57*2*ii), 205, 29+2*Parameters.cmCovers[ii], 150 );
}
// Ellipse2D.Double shape = new Ellipse2D.Double(balls.getX(), balls.getY(), balls.getVelocity(),balls.getRadius());
// g.fill(shape);
repaint();
}
}
public void funkcja()
{
repaint();
}
}
And my question is after uncommenting the // in Main my JTabbedPanel disappears.
I want paint to draw in JTab.
http://forum.4programmers.net/Java/232952-jtabbedpanel_i_paint?mode=download&id=6326 <-- While it is commented
http://forum.4programmers.net/Java/232952-jtabbedpanel_i_paint?mode=download&id=6327 <-- After uncommenting.
Iam kinda newbie in Java so I would like to get easy answers :P.
Hej,
replace this
JPanel tab1Panel = new JPanel();
with that
JPanel tab1Panel = new DrawingWindow();
up to now, you add the DrawingPanel to another JPanel, but if you want to draw on your Tab, then add create a JPanel, which you'll add to your JTabbedPane with addTab().
I'm currently working with JFrame and I'm trying to draw a rectangle but I don't know how to execute the code paint(Graphics g), how do I get the Graphics object?
package com.raggaer.frame;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Frame {
private JFrame frame;
public Frame() {
this.frame = new JFrame("Java Snake");
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.frame.setSize(new Dimension(500, 500));
// DRAW??
this.frame.setVisible(true);
}
public void paint(Graphics g) {
g.drawRect(10, 10, 200, 200);
}
}
Just call frame.repaint() (which should be called once automatically) to make it repaint the graphics. No need to provide your own Graphics object.
Side note, you should be using a JPanel with paintComponent(Graphics) instead. This will make handling of events a lot easier, especially for a game like snake.
Here is a small code example on Stack Overflow: Java drawing on JPanel which on a JFrame
And one I made myself with usage of Java 8:
import javax.swing.*;
import java.awt.*;
/**
* #author Obicere
*/
public class PaintExample {
public PaintExample() {
final JFrame frame = new JFrame("Paint Example");
final MyPanel panel = new MyPanel();
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(PaintExample::new);
}
public class MyPanel extends JPanel {
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
g.setColor(Color.YELLOW);
g.fillOval(0, 0, 50, 50);
g.setColor(Color.BLACK);
g.drawOval(0, 0, 50, 50);
g.drawLine(20, 10, 20, 20);
g.drawLine(30, 10, 30, 20);
g.drawArc(15, 15, 20, 20, 180, 180);
g.drawString("Drawing with swing!", 10, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
}
As request of your comment, I also modified the program to display objects upon request:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;
/**
* #author Obicere
*/
public class PaintExample {
public PaintExample() {
final JFrame frame = new JFrame("Paint Example");
final MyPanel panel = new MyPanel();
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(PaintExample::new);
}
public class MyPanel extends JPanel {
private final LinkedList<SmileyFace> faces;
public MyPanel() {
faces = new LinkedList<>();
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
faces.add(new SmileyFace(e.getX(), e.getY()));
MyPanel.this.repaint(); // Refresh the display on the screen
}
});
}
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
faces.stream().forEach((e) -> e.render(g));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public class SmileyFace {
private final int x;
private final int y;
public SmileyFace(final int x, final int y) {
this.x = x;
this.y = y;
}
public void render(final Graphics g) {
g.setColor(Color.YELLOW);
g.fillOval(x, y, 50, 50);
g.setColor(Color.BLACK);
g.drawOval(x, y, 50, 50);
g.drawLine(x + 20, y + 10, x + 20, y + 20);
g.drawLine(x + 30, y + 10, x + 30, y + 20);
g.drawArc(x + 15, y + 15, 20, 20, 180, 180);
}
}
}
I want to change the input in the textfield which will instantly update to the display, instead of press ENTER button to update it.
Here is my code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyProgram01 extends JFrame
{
private JTextField text1;
private JCheckBox check1;
private JCheckBox check2;
private String message;
private JLabel label1;
private JLabel label2;
private Font font;
public MyProgram01(String title)
{
super(title);
check1 = new JCheckBox("Bold");
check2 = new JCheckBox("Italics");
label1 = new JLabel("Text : ");
label2 = new JLabel("Style : ");
message = "Good Morning...";
text1 = new JTextField(message, 100);
font = new Font("Times New Roman", Font.PLAIN, 36);
setBounds(0, 0, 600, 300);
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setBounds(0, 0, 600, 120);
panel.setBackground(Color.ORANGE);
label1.setFont(new Font("Times New Roman", Font.PLAIN, 36));
label1.setBounds(15, 15, 100, 36);
panel.add(label1);
text1.setBounds(120, 15, 400, 36);
panel.add(text1);
label2.setFont(new Font("Times New Roman", Font.PLAIN, 36));
label2.setBounds(15, 65, 100, 36);
panel.add(label2);
check1.setBounds(120, 65, 100, 36);
check2.setBounds(220, 65, 100, 36);
panel.add(check1);
panel.add(check2);
check1.addActionListener(new CheckBoxListener());
check2.addActionListener(new CheckBoxListener());
text1.addActionListener(new TextFieldListener());
setLayout(null);
add(panel);
}
public void paint(Graphics g)
{
super.paint(g);
g.setFont(font);
g.drawString(message, 15, 255);
}
private class CheckBoxListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(check1.isSelected() && check2.isSelected())
{
font = new Font("Times New Roman", Font.BOLD + Font.ITALIC, 36);
repaint();
}
else if(check1.isSelected())
{
font = new Font("Times New Roman", Font.BOLD, 36);
repaint();
}
else if(check2.isSelected())
{
font = new Font("Times New Roman", Font.ITALIC, 36);
repaint();
}
else
{
font = new Font("Times New Roman", Font.PLAIN, 36);
repaint();
}
}
}
private class TextFieldListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
message = text1.getText();
repaint();
}
}
public static void main(String[] args)
{
JFrame frame = new MyProgram01("My Program 01");
frame.setVisible(true);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
How can I change the code to instantly update to the display?
EDIT :
It's work with the keyListener, but my program will only start display after second key is pressed.
For example, I key in abc, the program will start show a when I press b, and when I pressed c, it displays ab and c is missing, unless I press ENTER.
Here the part of the code :
text1.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
message = text1.getText();
repaint();
}
});
Add a KeyListener to your textfield.
You can do that like this:
textField.addKeyListener(new KeyAdapter(){
#Override
public void keyPressed(KeyEvent e){
message = textField.getText();
repaint();
}
});
OR
Add a DocumentListener to your textfield's Document.
You can do that like this:
private JFrame getFrame(){
return this;
}
...
textField.getDocument().addDocumentListener(new DocumentListener(){
#Override
public void insertUpdate(DocumentEvent e) {
message = textField.getText();
getFrame().repaint();
}
#Override
public void removeUpdate(DocumentEvent e) {
message = textField.getText();
getFrame().repaint();
}
#Override
public void changedUpdate(DocumentEvent e) {
// on change
}
});
Instead of using ActionListener for the class TextFieldListener, use KeyListener interface and use the keyTyped(KeyEvent e) method. When ever the event arises you can use getText() of texfield and repaint it.