Related
I am trying to start the program with jcheckbox hat selected and rectangle visible then the Rectangle disappears when the checkbox is unselected and repainted as checkbox is selected again. When I run the program and check the box another check box appears or left of the frame.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
public class Head extends JPanel {
JCheckBox hat;
public Head() {
hat = new JCheckBox("Hat");
hat.setSelected(true);
hat.addItemListener(new CheckSelection());
add(hat);
}
class CheckSelection implements ItemListener {
public void itemStateChanged(ItemEvent ie) {
repaint();
}
}
public void paintComponent(Graphics g) {
setForeground(Color.RED);
g.drawOval(110, 100, 100, 100);
g.drawOval(130, 120, 20, 15);
g.drawOval(170, 120, 20, 15);
g.drawLine(160, 130, 160, 160);
g.drawOval(140, 170, 40, 15);
if (hat.isSelected()) {
g.drawRect(100, 90, 120, 10);
}
}
public static void main(String[] args) {
Head head = new Head();
JFrame f = new JFrame();
f.add(head);
f.setSize(400, 400);
//f.setLayout(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
You've broken the paint chain by not calling the paintComponent's super method
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
setForeground(Color.RED);
g.drawOval(110, 100, 100, 100);
g.drawOval(130, 120, 20, 15);
g.drawOval(170, 120, 20, 15);
g.drawLine(160, 130, 160, 160);
g.drawOval(140, 170, 40, 15);
if (hat.isSelected()) {
g.drawRect(100, 90, 120, 10);
} else {
setForeground(Color.RED);
g.drawOval(110, 100, 100, 100);
g.drawOval(130, 120, 20, 15);
g.drawOval(170, 120, 20, 15);
g.drawLine(160, 130, 160, 160);
g.drawOval(140, 170, 40, 15);
}
}
The Graphics context is a shared resource between components, one of the jobs of paintComponent is to prepare the Graphics for painting, typically by filling it with the background color of the component. So failing to call super.paintComponent means that what ever was previously painted to the Graphics context will still be there
See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing
I'm having trouble with my buttons. I know they're working because I've tested them out by exiting the problem through System.exit. Here is what my output looks like:
http://imgur.com/Ks7mIFa
When I click the close button, the handle on the switch should redraw to the other side and the close button should change to open. When I click the open button, it should do the opposite. However, the buttons aren't doing anything. What am I doing wrong?
public class ProgrammingAssignment2 {
public static void main(String[] args) {
boolean ison = false;
// Objects
Circuit circuitObject = new Circuit();
Controller controllerObject = new Controller();
Draw drawObject = new Draw();
AllListeners listenerObject = new AllListeners();
drawObject.window();
circuitObject.buttons(drawObject, ison);
controllerObject.openFile("Programming Assignment 2 Data.txt", drawObject);
}
}
Class circuit just creates the buttons
import javax.swing.JButton;
public class Circuit {
public void buttons(Draw drawObject, boolean ison) {
AllListeners listenerObject = new AllListeners();
if (ison == true) {
JButton openButton = new JButton("Close");
openButton.addActionListener(listenerObject);
openButton.setBounds(200, 100, 50, 20);
drawObject.add(openButton);
} else if (ison == false) {
JButton closeButton = new JButton("Open");
closeButton.addActionListener(listenerObject);
closeButton.setBounds(50, 100, 50, 20);
drawObject.add(closeButton);
}
}
}
Draw class does most of the work. It creates all the graphics and reads in a text file that has the titles of each object(like switch and lightbulb).
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JFrame;
import java.awt.Graphics;
public class Draw extends JFrame {
private String[] line = new String[5];
private int counter = 0;
private boolean ison;
public void window() {
setSize(500, 500);
setTitle("Programming Assignment 2");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void readFile(String filename) {
counter = 1;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filename));
for (int i = 0; i < 4; i++) {
line[i] = br.readLine();
}
} catch (FileNotFoundException e) {
String error = "File was not found";
System.out.println(error.toString());
System.out.println("or could not be opened.");
} catch (IOException e) {
System.out.println("Error reading from file.");
} finally {
try {
br.close();
} catch (IOException e) {
System.out.println("Error closing file.");
}
}
}
public void paint(Graphics g) {
Circuit circuitObject = new Circuit();
super.paint(g);
if (ison == true) {
turnon(g);
circuitObject.buttons(this, ison);
} else {
turnoff(g);
}
}
public void setisOn() {
ison = true;
}
public void setisOff() {
ison = false;
}
public void turnoff(Graphics g) {
// Title
g.drawString(line[0], 150, 40);
//Switch
g.drawString(line[2], 130, 190);
g.drawRect(100, 150, 100, 20);
g.drawOval(115, 155, 10, 10);
g.drawOval(175, 155, 10, 10);
g.drawArc(140, 140, 20, 20, 180, -180);
//off switch
g.drawLine(160, 150, 182, 133);
g.drawLine(157, 142, 173, 128);
g.drawLine(173, 128, 182, 133);
//Power Supply
g.drawString(line[1], 50, 420);
g.drawRect(50, 320, 50, 80);
g.drawLine(50, 320, 70, 290);
g.drawLine(100, 320, 120, 290);
g.drawLine(70, 290, 120, 290);
g.drawLine(120, 370, 120, 290);
g.drawLine(120, 370, 100, 400);
//plus
g.drawLine(94, 310, 100, 310);
g.drawLine(97, 307, 97, 313);
// minus
g.drawLine(100, 300, 107, 300);
// pliers
g.drawRect(70, 305, 5, 10);
g.drawRect(90, 288, 5, 10);
//lightbulb
g.drawString(line[3], 400, 250);
g.drawRect(400, 200, 20, 20);
g.drawOval(395, 170, 30, 30);
// pliers
g.drawRect(400, 220, 5, 10);
g.drawRect(415, 220, 5, 10);
// plus wire to switch
g.drawLine(72, 305, 120, 160);
//bulb to switch
g.drawLine(180, 160, 400, 230);
//bulb to minus
g.drawLine(90, 290, 420, 230);
}
public void turnon(Graphics g) {
// Title
g.drawString(line[0], 150, 40);
//Switch
g.drawString(line[2], 130, 190);
g.drawRect(100, 150, 100, 20);
g.drawOval(115, 155, 10, 10);
g.drawOval(175, 155, 10, 10);
g.drawArc(140, 140, 20, 20, 180, -180);
//on switch
g.drawLine(140, 150, 122, 133);
g.drawLine(143, 142, 129, 128);
g.drawLine(122, 133, 129, 128);
//Power Supply
g.drawString(line[1], 50, 420);
g.drawRect(50, 320, 50, 80);
g.drawLine(50, 320, 70, 290);
g.drawLine(100, 320, 120, 290);
g.drawLine(70, 290, 120, 290);
g.drawLine(120, 370, 120, 290);
g.drawLine(120, 370, 100, 400);
//plus
g.drawLine(94, 310, 100, 310);
g.drawLine(97, 307, 97, 313);
// minus
g.drawLine(100, 300, 107, 300);
// pliers
g.drawRect(70, 305, 5, 10);
g.drawRect(90, 288, 5, 10);
//lightbulb
g.drawString(line[3], 400, 250);
g.drawRect(400, 200, 20, 20);
g.drawOval(395, 170, 30, 30);
// pliers
g.drawRect(400, 220, 5, 10);
g.drawRect(415, 220, 5, 10);
// plus wire to switch
g.drawLine(72, 305, 120, 160);
//bulb to switch
g.drawLine(180, 160, 400, 230);
//bulb to minus
g.drawLine(90, 290, 420, 230);
}
}
Controller doesn't do much right.
public class Controller {
public void openFile(String filename, Draw drawObject) {
drawObject.readFile(filename);
}
}
And this is the actionlisterner class
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class AllListeners implements ActionListener {
public void actionPerformed(ActionEvent e) {
Circuit circuitObject = new Circuit();
Draw drawObject = new Draw();
String buttonString = e.getActionCommand();
if (buttonString.equals("Close")) {
drawObject.setisOn();
drawObject.repaint();
} else if (buttonString.equals("Open")) {
drawObject.setisOff();
drawObject.repaint();
} else {
System.out.println("Unexpected error.");
}
}
}
You've got lots of major problems with this code including:
Drawing directly within a JFrame's paint method, something fraught with problems as you risk messing up the JFrame's own complicated painting.
Placing program logic within a painting method, a method you don't have full control over when or if it fires, and one that you shouldn't slow down
Placing component creation code within a painting method.
Trying to add multiple JButtons willy nilly rather than changing the state of an existing component.
Creating multiple Circuit objects.
Trying to use absolute positioning via setBounds(...) to place a component in a container that uses BorderLayout.
I suggest that you
Start over and scrap this code.
Draw only in a JPanel's paintComponent method, just as the tutorials will tell you to do.
Create your buttons once and only once and add them to your GUI.
Get all program logic out of the painting (here paintComponent) method, and all object state changing outside of that method as they are for painting and painting only.
Instead the logic should belong to the controller, and which should be notified of the button push.
So consider having the button push notify the control what was pushed,
the control changes the state of the program (changes variables)
and then it calls repaint so that the paintComponent method can use those variables to change its drawing.
Also, avoid using setBounds and null layouts if at all possible, and instead use layout managers/borders/nested JPanels to help you place your components.
So, I am going to have more of these panels but I don't know how to make these panels switch when the user will press a button like start or next.
//IngestionOfDigestion.java teaches the user about the digestive system through interactive components
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class IngestionOfDigestion extends JFrame {
public static void main(String[] args) {
IngestionOfDigestion i = new IngestionOfDigestion();
}
public IngestionOfDigestion() {//frame header
//make the frame
super("Ingestion Of Digestion");
setSize(1900, 1100);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocation(10, 50);
setResizable(true);
layout t = new layout();
add(t);
setContentPane(t);
setVisible(true);
}
}
class layout extends JPanel {
public Mouth m;
public CardLayout cardlay = new CardLayout();
Title title = new Title();
public layout() {
m = new Mouth();
cardlay.show();
setLayout(cardlay);
add(m, "Mouth");
add(title, "Title");
}
}
class Title extends JPanel implements ActionListener {//make title panel
private JButton c;//jbutton to start the game
private boolean startpressed;//button pressed variable
//JPanel card2;
//JPanel card3;
public Title() {//title method header
//cardstack = new JPanel(cardlay);
c = new JButton("Press to start playing");//make jbutton saying start the game
c.addActionListener(this);
add(c);
startpressed = false;
}
public void paintComponent(Graphics g) { //paint component
super.paintComponent(g);//super.paintComponent
Font title = new Font("Serif", Font.BOLD, 90);//make font
g.setFont(title);
g.drawString("Ingestion Of Digestion", 160, 100);//draw the title
if (startpressed == true) {//if buttonpressed is true
repaint();
}
}
public void actionPerformed(ActionEvent e) {//ActionPerformed
if (e.getSource() == c) {
startpressed = true;//change boolean
cardlay.next();
repaint();
}
}
}
//if button is pressed
//end title panel
class Mouth extends JPanel implements ActionListener, ChangeListener {
private JButton chew;//make chew button
private JButton next;//next button
private JSlider saliva;//make saliva slider
private boolean nextpressed;//nextbuttonpressed variable
private boolean chewpressed;//buttonpressed variable
Mouth() {//mouth method
chew = new JButton("Press to chew the food");
chew.addActionListener(this);
add(chew);
chewpressed = false;
JSlider saliva = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
add(saliva);
next = new JButton("Press to go to the next step of digestion");
next.addActionListener(this);
add(next);
nextpressed = false;
}
public void paintComponent(Graphics g) {//paint component
super.paintComponent(g);//super.paintComponent
//draw the head
Color skin = new Color(255, 204, 133);
g.setColor(skin);
g.fillArc(810, 1000, 550, 550, 0, 180);
g.fillRect(1085, 600, 150, 550);
g.fillRect(700, 250, 535, 380);
int[] w = {700, 700, 660};
int[] t = {340, 420, 420};
g.fillPolygon(w, t, 3);
Color hair = new Color(100, 60, 0);
g.setColor(hair);
g.fillArc(700, 175, 535, 150, 0, 180);
g.setColor(Color.WHITE);
g.fillOval(730, 275, 45, 45);
g.setColor(Color.BLACK);
g.fillOval(752, 297, 15, 15);
g.setColor(Color.RED);
g.fillRect(700, 480, 285, 75);
g.fillRect(985, 497, 145, 45);
g.fillRect(1130, 497, 30, 590);
g.setColor(Color.WHITE);
g.fillRect(702, 480, 15, 20);
g.fillRect(719, 480, 15, 20);
g.fillRect(736, 480, 15, 20);
g.fillRect(753, 480, 24, 20);
g.fillRect(779, 480, 24, 20);
g.fillRect(805, 480, 24, 20);
g.fillRect(702, 535, 15, 20);
g.fillRect(719, 535, 15, 20);
g.fillRect(736, 535, 15, 20);
g.fillRect(753, 535, 24, 20);
g.fillRect(779, 535, 24, 20);
g.fillRect(805, 535, 24, 20);
if (chewpressed == true) {
Color skint = new Color(255, 204, 133);
g.setColor(skint);
g.fillArc(810, 1000, 550, 550, 0, 180);
g.fillRect(1085, 600, 150, 550);
g.fillRect(700, 250, 285, 380);
int[] wt = {700, 700, 660};
int[] tw = {340, 420, 420};
g.fillPolygon(w, t, 3);
Color hairt = new Color(100, 60, 0);
g.setColor(hairt);
g.fillArc(700, 175, 535, 150, 0, 180);
g.setColor(Color.WHITE);
g.fillOval(730, 275, 45, 45);
g.setColor(Color.BLACK);
g.fillOval(752, 297, 15, 15);
g.setColor(Color.RED);
g.fillRect(700, 480, 285, 42);
g.fillRect(985, 497, 145, 35);
g.fillRect(1130, 497, 30, 590);
g.setColor(Color.WHITE);
g.fillRect(702, 480, 15, 20);
g.fillRect(719, 480, 15, 20);
g.fillRect(736, 480, 15, 20);
g.fillRect(753, 480, 24, 20);
g.fillRect(779, 480, 24, 20);
g.fillRect(805, 480, 24, 20);
g.fillRect(702, 502, 15, 20);
g.fillRect(719, 502, 15, 20);
g.fillRect(736, 502, 15, 20);
g.fillRect(753, 502, 24, 20);
g.fillRect(779, 502, 24, 20);
g.fillRect(805, 502, 24, 20);
repaint();
}
}
public void actionPerformed(ActionEvent e) {//ActionPerformed
if (chew.getText().equals("Press to chew the food")) {//if "press my belly" pressed,
chewpressed = true;//change boolean
repaint();
if (next.getText().equals("Press to go to the next step of digestion")) {
nextpressed = true;
}
repaint();
}
}
public void stateChanged(ChangeEvent e) {
int location1 = saliva.getValue();
}
}
//draw the info
//if buttonpressed is true
//show head with teeth clenched
//else if slidermoved is true
//show saliva moving in mouth
//else if nextbuttonpressed is true
//go to next panel
//ActionPerformed
//if button is pressed
//buttonpressed is true
//else if slider is moved
//slidermoved is true
//else if next button is pressed
//nextbuttonpressed is true
I'm new to Java and I am currently developing a GUI for a Blackjack game. I am having problems displaying components on a screen via the paint method. The paint method is located in a subclass called play (see below). When paint is located outside play but inside BlackJack it works. Could someone help me?
public class BlackJack extends JFrame
{
.
.
.
public class play implements ActionListener
{
.
.
.
public void paint(Graphics g)
{
super.paint(g);
Font bigFont = new Font("HURTMOLD_", Font.BOLD, 20);
g.setFont(bigFont);
g.setColor(Color.decode("#52504D"));
g.drawString("Dealer", 50, 80);
g.drawString("Player", 50, 290);
g.setColor(Color.white);
g.drawLine(120, 76, 700, 76);
g.drawLine(20, 76, 40, 76);
g.drawLine(20, 240, 700, 240);
g.drawLine(20, 76, 20, 240);
g.drawLine(700, 76, 700, 240);
g.drawLine(120, 286, 700, 286);
g.drawLine(20, 286, 40, 286);
g.drawLine(20, 450, 700, 450);
g.drawLine(20, 286, 20, 450);
g.drawLine(700, 286, 700, 450);
g.setColor(Color.blue);
g.fillRect(50,113,71,96);
g.fillRect(151,113,71,96);
g.fillRect(252,113,71,96);
g.fillRect(353,113,71,96);
g.fillRect(454,113,71,96);
}
.
.
.
}
}
Play is not a subclass of anything that Swing knows how to paint. You can't just implement a paint method in your class and have it magically work.
Try adding #Override before the paint method
#Override
public void paint(Graphics g)
{
It will fail to compile. The reason it does compile know, is the compiler is inferring the call to super.paint as been the JFrame's paint method, which you really don't want to do.
Instead, try extending Play from something like JPanel and overriding it's paintComponent method instead, then add an instance of Play to the frame, like any other component.
public class Play extends JPanel implements ActionListener
{
.
.
.
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Font bigFont = new Font("HURTMOLD_", Font.BOLD, 20);
g.setFont(bigFont);
g.setColor(Color.decode("#52504D"));
g.drawString("Dealer", 50, 80);
g.drawString("Player", 50, 290);
g.setColor(Color.white);
g.drawLine(120, 76, 700, 76);
g.drawLine(20, 76, 40, 76);
g.drawLine(20, 240, 700, 240);
g.drawLine(20, 76, 20, 240);
g.drawLine(700, 76, 700, 240);
g.drawLine(120, 286, 700, 286);
g.drawLine(20, 286, 40, 286);
g.drawLine(20, 450, 700, 450);
g.drawLine(20, 286, 20, 450);
g.drawLine(700, 286, 700, 450);
g.setColor(Color.blue);
g.fillRect(50,113,71,96);
g.fillRect(151,113,71,96);
g.fillRect(252,113,71,96);
g.fillRect(353,113,71,96);
g.fillRect(454,113,71,96);
}
.
.
.
}
}
I am having trouble inserting an image on top of a paint method that I've written. I want to have images overlap the paint method at certain coordinates.
My code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class testguipaint {
public static void main(String[] args) {
testguipaint img = new testguipaint();
}
public testguipaint() {
JFrame frame = new JFrame();
frame.add(crafting, BorderLayout.CENTER);
frame.setSize(442, 284);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(3);
}
static JPanel crafting = new JPanel() {
public void paint(Graphics g) {
Color darkGrey = new Color(153, 153, 153);
g.setColor(darkGrey);
g.fillRect(0, 0, 436, 252);
Color lightGrey = new Color(198, 198, 198);
g.setColor(lightGrey);
g.fill3DRect(3, 3, 430, 246, true);
g.setColor(darkGrey);
g.fill3DRect(16, 16, 222, 222, true);
g.fill3DRect(320, 78, 100, 100, true);
g.fillRect(248, 121, 39, 12);
Polygon triangle = new Polygon();
triangle.addPoint(287, 103);
triangle.addPoint(287, 151);
triangle.addPoint(311, 127);
g.fillPolygon(triangle);
g.setColor(Color.white);
g.fill3DRect(88, 16, 3, 222, true);
g.fill3DRect(163, 16, 3, 222, true);
g.fill3DRect(16, 88, 222, 3, true);
g.fill3DRect(16, 163, 222, 3, true);
//BufferedImage image = new ImageIO.read(new File("/minecraft jpeg's/Products/Bread.png"));
//g.drawImage(image, 44, 191, null);
//44, 191
}
};
}
not an answer how to overlay or overlap
1) testguipaint should be TestGuiPaint more about Java Naming Conventions here or here
2) Swing GUI rellated code should be wrapped into invokeLater(), more about in the Initial Threads
3) for painting in Swing JComponents there is method paintComponent() instead of paint() method, more about in the 2D Graphics
Just a suggestion, paint the images last in the paint component. This would allow the images to by drawn on top of the other objects. Also, I know that you were probably just testing something, but the first letter of every word in your class name should be capitalized.
Condensing the imports only for short code here, implementing only 2 of the suggestions MKorbel made (1 and 3), extending JFrame for brevity too, removed instance from main, which was never used. Nothing you asked for.
But you surely don't want to have the image read over and over again from HDD, each time the Panel needs repainting. So we create an instance which holds an attribute, which is the image.
import java.awt.*;
import javax.swing.*;
import javax.swing.JPanel;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
public class TestGuiPaint extends JFrame {
public static void main (String [] args) {
new TestGuiPaint ();
}
public TestGuiPaint () {
super ("TestGuiPaint");
add (new CraftingPanel (), BorderLayout.CENTER);
setSize (442, 284);
setLocationRelativeTo (null);
setResizable (false);
setVisible (true);
setDefaultCloseOperation (3);
}
class CraftingPanel extends JPanel {
BufferedImage image = null;
public CraftingPanel () {
try {
image = ImageIO.read (new File ("./maeander3.png"));
} catch (java.io.IOException ioe)
{
System.err.println (ioe.getMessage ());
}
}
public void paintComponent (Graphics g) {
Color darkGrey = new Color (153, 153, 153);
g.setColor (darkGrey);
g.fillRect (0, 0, 436, 252);
Color lightGrey = new Color (198, 198, 198);
g.setColor (lightGrey);
g.fill3DRect (3, 3, 430, 246, true);
g.setColor (darkGrey);
g.fill3DRect (16, 16, 222, 222, true);
g.fill3DRect (320, 78, 100, 100, true);
g.fillRect (248, 121, 39, 12);
Polygon triangle = new Polygon ();
triangle.addPoint (287, 103);
triangle.addPoint (287, 151);
triangle.addPoint (311, 127);
g.fillPolygon (triangle);
g.setColor (Color.white);
g.fill3DRect (88, 16, 3, 222, true);
g.fill3DRect (163, 16, 3, 222, true);
g.fill3DRect (16, 88, 222, 3, true);
g.fill3DRect (16, 163, 222, 3, true);
g.drawImage (image, 44, 191, null);
}
};
}
I hope you understand that I've chosen a different filename for the image. :)