So I want to set my Rectangle's color to whatever the JColorChooser picks, but unfortunately, I don't think that it recognises it as it just stays black, unless I assign it a real color like Color.BLUE.
This is the rectangle which should get the color from the other class:
TestProjectJPanel jpp = new TestProjectJPanel();
public void paintComponent(Graphics g){
super.paintComponent(g);
Rectangle r = new Rectangle(500,300,250,400);
g.setColor(jpp.bodyColour);
g.fillRect((int)r.getX(),(int)r.getY(),(int)r.getHeight(),(int)r.getWidth());
g.setColor(Color.BLUE);
g.drawString("banana", 50, 60);
}
and this is the class which has the color itself
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestProjectJPanel extends JFrame {
public JButton b;
public JButton u;
public JButton l;
public JButton r;
public String s;
public Color color = (Color.WHITE);
public JPanel panel;
public Color bodyColour;
public Color doorColour;
public Color wheelColour;
public TestProjectJPanel(){
JFrame f = new JFrame();
panel = new JPanel();
panel.setBackground(color);
// bodyColour button
b = new JButton("Body Colour");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
bodyColour = JColorChooser.showDialog(null, "Pick the colour", bodyColour);
if (bodyColour == null)
bodyColour = Color.RED;
}
});
u = new JButton("Wheel Colour");
u.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
wheelColour = JColorChooser.showDialog(null, "Pick the colour", wheelColour);
if (wheelColour == null)
wheelColour = (Color.BLACK);
}
});
l = new JButton("Door Colour");
l.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
doorColour = JColorChooser.showDialog(null, "Pick the colour", doorColour);
if(doorColour==null)
doorColour = (Color.RED);
}
});
r = new JButton("Change Name");
r.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
s = JOptionPane.showInputDialog("What name do you want to change it to?");
}
});
}
}
This is the whole code, which the Rectangle is included in.
import javax.swing.*;
import java.util.*;
import java.awt.*;
public class TestProjectDialog extends JPanel {
TestProjectJPanel jpp = new TestProjectJPanel();
public void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle r = new Rectangle(500, 300, 250, 400);
g.setColor(jpp.bodyColour);
g.fillRect((int) r.getX(), (int) r.getY(), (int) r.getHeight(), (int) r.getWidth());
g.setColor(Color.BLUE);
g.drawString("banana", 50, 60);
}
public static void main(String[] args){
TestProjectJPanel jpp = new TestProjectJPanel();
/* JOptionPane.showMessageDialog(null, "Just about to draw a REALLY GOOD 2D car \n just need input please.");
jpp.s = JOptionPane.showInputDialog("Imagine a car, what is it's name?");
if(jpp.s == null || (jpp.s != null && ("".equals(jpp.s))))
{
JOptionPane.showMessageDialog(null, "Invalid input/pressed cancel, closing program.");
System.exit(0);
}
JOptionPane.showMessageDialog(null, "Ah okay, so it's name is " + jpp.s); */
JFrame f = new JFrame("My 2D Car Drawing");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jpp.setBackground(Color.WHITE);
f.setSize(1440,900);
f.add(new TestProjectDialog(), BorderLayout.CENTER);
f.add(jpp.b, SpringLayout.SOUTH); // bodyColour
// f.add(jpp.u, SpringLayout. NORTH); // wheelColour
// f.add(jpp.l, SpringLayout.WEST); // doorColour
// f.add(jpp.r, SpringLayout.EAST); // changeName
f.setVisible(true);
}
}
Could anyone help me and give me a solution for why it's not recognising the color?
Without a runnable example that demonstrates your problem, it is impossible to 100% sure, but from the sounds of it, you have created two more instances of TestProjectJPanel and/or paint panel, so what you think you're drawing to isn't actually on the screen.
However, it also sounds like you're not adhering to basic OO design, ensuring that the object is self managed, but instead, allowing the object to ascertain it's state from the properties of another object.
Instead, your paint/rectangle pane should be self contained, that is, all the properties it needs should be managed by it (this could also include a model, but that's going beyond the problem at hand).
For example, the ControlPane manages the interactions between the user (choosing a color) and the setting of that color on the PaintPane, which deals only with painting the results...
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ColorTest {
public static void main(String[] args) {
new ColorTest();
}
public ColorTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
PaintPane paintPane = new PaintPane();
ControlPane controlPane = new ControlPane(paintPane);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(paintPane);
frame.add(controlPane, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ControlPane extends JPanel {
public ControlPane(PaintPane paintPane) {
JButton colorButton = new JButton("Color");
add(colorButton);
colorButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(ControlPane.this, "Background", paintPane.getFillColor());
if (color != null)
paintPane.setFillColor(color);
}
});
}
}
public class PaintPane extends JPanel {
private Color fillColor = Color.RED;
public PaintPane() {}
public Color getFillColor() {
return fillColor;
}
public void setFillColor(Color fillColor) {
this.fillColor = fillColor;
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(fillColor);
g2d.fillRect(50, 50, 100, 100);
g2d.dispose();
}
}
}
Related
Code: Java Sphere class
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
public class Sphere extends JPanel {
private boolean flashinglights = false;
private int x = 168;
private int y = 75;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (flashinglights) { //This is the flash option. Here it should change between grey and orange
g2.setColor(Color.ORANGE);
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
g2.draw(ball);
g2.fill(ball);
} else {
g2.setColor(Color.gray); //This should stay grey as it does now.
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
g2.draw(ball);
g2.fill(ball);
}
}
public void chooseflashinglights(){ //Ignore these methods
flashinglights = false;
}
public void choosesteady(){
flashinglights = true;
}
public void flickerorange(int d) { y = y + d; }
public void flickergrey(int d) { y = y + d; }
public static void main(String[] args) {
JFrame scFrame = new AnimationViewer();
scFrame.setTitle("Circle");
scFrame.setSize(400, 400);
scFrame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
scFrame.setVisible(true);
}
}
Animation Viewer Class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class AnimationViewer extends JFrame {
JButton jbtFlash = new JButton("Flash");
JButton jbtSteady = new JButton("Steady");
JPanel bPanel = new JPanel();
Sphere sphPanel = new Sphere();
Timer timer;
public AnimationViewer() {
this.add(bPanel, BorderLayout.SOUTH);
bPanel.add(jbtFlash);
bPanel.setLayout(new GridLayout(1,2));
bPanel.add(jbtSteady);
this.add(sphPanel, BorderLayout.CENTER);
jbtSteady.addActionListener(new SteadyLights());
jbtFlash.addActionListener(new FlashingLights());
timer = new Timer(100, new TimerListener());
timer.start();
}
class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
sphPanel.flickerorange(0);
sphPanel.flickergrey(0);
repaint();
}
}
class FlashingLights implements ActionListener{
public void actionPerformed(ActionEvent e){
sphPanel.chooseflashinglights();
}
}
class SteadyLights implements ActionListener{
public void actionPerformed(ActionEvent e){
sphPanel.choosesteady();
}
}
}
So right now there is a sphere that appears on the screen. There are two buttons showed below. Flash and Steady. On the steady button it has to stay one colour (orange) which it does not.
Now on Flash it has to change from Orange to grey every 100 milli seconds.
I know it has to be something to do with Action listeners but how exactly do I implement this?
You have a lot of extra code. I would do it like this. Write flashing logic in paintComponent method. Then create just one timer. On tick call the paintComponent method for every 100ms. On flash button click start the timer, on steady button click stop the timer and call paintComponent once.
Sphere class:
public class Sphere extends JPanel {
private boolean flashinglights = false;
private int x = 168;
private int y = 75;
private Color[] colors = new Color[] {Color.ORANGE, Color.GRAY };
private int colorIndex = 0;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (!flashinglights) {
g2.setColor(Color.ORANGE);
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
g2.draw(ball);
g2.fill(ball);
} else {
if(colorIndex > colors.length - 1)
colorIndex = 0;
g2.setColor(colors[colorIndex++]);
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
g2.draw(ball);
g2.fill(ball);
}
}
public void chooseflashinglights(){ //Ignore these methods
flashinglights = true;
}
public void choosesteady(){
flashinglights = false;
}
public static void main(String[] args) {
JFrame scFrame = new AnimationViewer();
scFrame.setTitle("Circle");
scFrame.setSize(400, 400);
scFrame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
scFrame.setVisible(true);
}
}
AnimationViewer class:
public class AnimationViewer extends JFrame {
JButton jbtFlash = new JButton("Flash");
JButton jbtSteady = new JButton("Steady");
JPanel bPanel = new JPanel();
Sphere sphPanel = new Sphere();
Timer timer;
public AnimationViewer() {
this.add(bPanel, BorderLayout.SOUTH);
bPanel.add(jbtFlash);
bPanel.setLayout(new GridLayout(1,2));
bPanel.add(jbtSteady);
this.add(sphPanel, BorderLayout.CENTER);
timer = new Timer(100, new TimerListener());
jbtSteady.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
sphPanel.choosesteady();
timer.stop();
sphPanel.repaint();
}
});
jbtFlash.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
sphPanel.chooseflashinglights();
timer.start();
}
});
}
class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
sphPanel.repaint();
}
}
}
I would do things a bit differently.
I'd have a field in my drawing JPanel class that indicates what color should be shown.
For instance, if there are only two colors that are swapped, I'd use a boolean field, and would swap it's value in my timer, and then base the color draw on its value.
The paintComponent method would use that field, the boolean, to decide which Color to use for g.setColor(...).
If many colors are drawn, the field could be a combination of an array of Color together with an int index into the array. Then I'd increment the index as needed, and use the index in paintComponent to decide which color to draw with.
I'd change that field in my Timer's ActionListener -- just a single call to change it, not your strange call to flicker orange and flicker gray.
I'd start the Timer with one button
I'd stop it with the other button. That's all the button's action listener would do, simply start or stop the timer.
I have to build a GUI that takes 4 colorable shapes (MyShape class) that are going to be grey in the beginning. Later, writing the RGB values on the three JTextField on the bottom of the GUI i'll be able to set the new color that will paint every picture that I'll click later.
Everything works great except the fact that in the DocumentListener i can't use the setText method or I'll get an IllegalStateException. I'd like to call that method in order to correct a wrong value of an RGB component: for instance, if the user writes 500, the text will automatically set the JTextField to 255.
Here is the code of the full project, so that you can run it (in the code I commented the line right before the method with the problem (I know it's kinda long to read, thank you if you'll help me anyway! :) ):
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.util.Arrays;
import java.util.List;
public class ShapesGUI extends JFrame {
private ShapesPlayGround shapesPlayGround;
private ColorPreview colorPreview;
private RGB rgb;
private List<MyShape> shapeList;
public ShapesGUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
Container cnt = getContentPane();
shapesPlayGround = new ShapesPlayGround();
colorPreview = new ColorPreview();
rgb = new RGB();
cnt.add(shapesPlayGround, BorderLayout.CENTER);
cnt.add(colorPreview, BorderLayout.WEST);
cnt.add(rgb, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public void setShapeList(List<MyShape> shapeList) {this.shapeList = shapeList;}
class ShapesPlayGround extends JPanel {
MyShape[] shapes;
public ShapesPlayGround() {
setPreferredSize(new Dimension(800, 450));
setBorder(new TitledBorder("Shapes"));
shapes = new MyShape[4];
shapes[0] = new MyShape(new Rectangle2D.Double(50, 250, 40, 180)); // Rettangolo, basso sinistra
shapes[1] = new MyShape(new Rectangle2D.Double(500, 100, 250, 250)); // Quadrato, estrema destra
shapes[2] = new MyShape(new Ellipse2D.Double(75, 50, 250, 120)); // Ellisse, alto sinistra
shapes[3] = new MyShape(new Ellipse2D.Double(310, 200, 230, 230)); // Cerchio, destra
setShapeList(Arrays.asList(shapes));
addMouseListener(new MyMouseListener());
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for (MyShape shape : shapes) {
g2.setPaint(shape.getColor());
g2.fill(shape.getShape());
g2.setPaint(Color.black);
g2.draw(shape.getShape());
}
}
class MyMouseListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
if (shapeList != null) {
for (MyShape shape : shapes) {
if (shape.getShape().contains(p)) {
shape.setColor(rgb.getColor());
}
repaint();
}
}
}
}
}
class ColorPreview extends JPanel {
int[] rgbValue = new int[3];
JPanel panel;
Shape preview;
public ColorPreview() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JLabel(" Preview "));
panel = new JPanel();
panel.setBorder(new TitledBorder("Color"));
add(panel);
}
public void setColor(int[] rgbValue) {this.rgbValue = rgbValue;}
public int[] getColor() {return rgbValue;}
public void paintColor() {
Graphics2D g2 = (Graphics2D)getGraphics();
preview = new Rectangle2D.Double(panel.getX() + 5, panel.getY() + 20, panel.getWidth() - 10, panel.getWidth() - 10);
g2.setPaint(rgb.getColor());
g2.fill(preview);
}
}
class RGB extends JPanel {
private JPanel[] rgbPanel = new JPanel[3];
private String[] panelTitles = {"Red", "Green", "Blue"};
private JTextField[] rgbText = new JTextField[3];
private JTextField[] partialColor = new JTextField[3];
private Shape[] rgbShape;
private int[] rgbValue = new int[3];
private Color color;
public RGB() {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
for (int i = 0; i < 3; i++) {
rgbPanel[i] = new JPanel();
rgbPanel[i].setLayout(new GridLayout(1, 2));
rgbPanel[i].setBorder(new TitledBorder(panelTitles[i]));
rgbText[i] = new JTextField();
partialColor[i] = new JTextField();
rgbValue[i] = 0;
rgbText[i].setText("0");
rgbText[i].getDocument().addDocumentListener(new TextChanged(i));
partialColor[i].setBackground(Color.black);
partialColor[i].setEditable(false);
rgbPanel[i].add(rgbText[i]);
rgbPanel[i].add(partialColor[i]);
add(rgbPanel[i]);
}
color = new Color(rgbValue[0], rgbValue[1], rgbValue[2]);
}
public int[] getRgbValue() {return rgbValue;}
public Color getColor() {return color;}
public void setRgbValue(int[] rgbValue) {this.rgbValue = rgbValue;}
public void setColor(Color color) {this.color = color;}
class TextChanged implements DocumentListener {
private int i;
public TextChanged(int i) {this.i = i;}
#Override
public void insertUpdate(DocumentEvent e) {listen(i);}
#Override
public void removeUpdate(DocumentEvent e) {listen(i);}
#Override
public void changedUpdate(DocumentEvent e) {listen(i);}
private int fixValue(int value) {return value < 0 ? 0 : (value > 255 ? 255 : value);}
// HERE'S THE PROBLEM!!!
private void listen(int i) {
try {
rgbValue[i] = fixValue(Integer.parseInt(rgbText[i].getText()));
} catch (NumberFormatException e) {
rgbValue[i] = 0;
}
color = new Color(rgbValue[0], rgbValue[1], rgbValue[2]);
rgb.setColor(color);
colorPreview.paintColor();
try {
rgbText[i].setText("" + rgbValue[i]);
} catch (IllegalStateException e) {
System.out.println("~Shit, Exception");
}
if (i == 0) partialColor[0].setBackground(new Color(rgbValue[0], 0, 0));
else if (i == 1) partialColor[1].setBackground(new Color(0, rgbValue[1], 0));
else if (i == 2) partialColor[2].setBackground(new Color(0, 0, rgbValue[2]));
}
}
}
public static void main(String args[]) {
new ShapesGUI();
}
}
One possible solution is to wrap your change to the text in a Runnable and queue it on the event thread using SwingUtilitiles.invokeLater(yourRunnable), but better perhaps ..... you're trying to correct the input before it is fully registered in the text component. In this situation, don't use a DocumentListener, but rather use a DocumentFilter.
Better still -- use a JSlider or a JSpinner
e.g.,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SpinnerEg extends JPanel {
private Map<RGB, JSlider> sliderMap = new EnumMap<>(RGB.class);
private JPanel displayPanel = new JPanel();
private Color displayPanelColor = new Color(0, 0, 0);
public SpinnerEg() {
displayPanel.setBackground(displayPanelColor);
JPanel sliderPanel = new JPanel(new GridLayout(1, 0));
for (RGB rgb : RGB.values()) {
createRgbSlider(sliderPanel, rgb);
}
displayPanel.setPreferredSize(new Dimension(400, 400));
setLayout(new BorderLayout());
add(displayPanel);
add(sliderPanel, BorderLayout.PAGE_END);
}
private void createRgbSlider(JPanel sliderPanel, final RGB rgb) {
final JSlider slider = new JSlider(0, 255, 0);
slider.setMajorTickSpacing(50);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
sliderMap.put(rgb, slider);
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
int red = sliderMap.get(RGB.RED).getValue();
int green = sliderMap.get(RGB.GREEN).getValue();
int blue = sliderMap.get(RGB.BLUE).getValue();
displayPanelColor = new Color(red, green, blue);
displayPanel.setBackground(displayPanelColor);
}
});
JPanel rgbPanel = new JPanel(new BorderLayout());
rgbPanel.setBorder(BorderFactory.createTitledBorder(rgb.getName()));
rgbPanel.add(slider);
sliderPanel.add(rgbPanel);
}
private static void createAndShowGui() {
SpinnerEg mainPanel = new SpinnerEg();
JFrame frame = new JFrame("SpinnerEg");
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();
}
});
}
}
enum RGB {
RED("Red", Color.red), GREEN("Green", Color.green), BLUE("Blue", Color.blue);
private String name;
private Color color;
private RGB(String name, Color color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public Color getColor() {
return color;
}
}
I am printing various elements such as text and images using the Panels and components it is generating pages for printing and print is also coming but the hard print also has the print button on physical paper. I to remove the print button from the page. here is the code
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.print.*;
public class Printing extends JFrame
implements ActionListener {
public static void main(String[] args)
{
// intialise
}
public Printing(String Firstname,String LastName,String contactid)
{
super("Print badge");
WindowUtilities.setNativeLookAndFeel();
addWindowListener(new ExitListener());
Container content = getContentPane();
JButton printButton = new JButton("Print");
printButton.addActionListener(this);
JPanel buttonPanel = new JPanel();
buttonPanel.setBackground(Color.BLACK);
buttonPanel.add(printButton);
content.add(buttonPanel, BorderLayout.SOUTH);
DrawingPanel drawingPanel = new DrawingPanel(Firstname,LastName,contactid);
content.add(drawingPanel, BorderLayout.CENTER);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent event)
{
//call for printing
}
}
and code for actual printing panel
public class DrawingPanel extends JPanel
{
private int fontSize1 = 32;
private Image img1=null;
public DrawingPanel(String n1,String n2,String n3)
{
String path="D:"+"\\25175.jpg";
setBackground(Color.white);
Font font = new Font("Serif", Font.PLAIN, 32);
setFont(font);
img1=new ImageIcon(path).getImage();
setPreferredSize(new Dimension(400, 400));
}
public void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
g2d.translate(x, y);
g2d.setPaint(Color.lightGray);
AffineTransform origTransform = g2d.getTransform();
g2d.shear(-0.95, 0);
g2d.scale(1, 3);
g2d.setTransform(origTransform);
g2d.setPaint(Color.BLUE);
g2d.drawString(string,25 , 50);
g2d.drawString(string, 125,100);
g.drawImage(img1, 280, 190, null);
}
}
The print method setup is here
import java.awt.*;
import javax.swing.*;
import java.awt.print.*;
public class PrintUtilities implements Printable {
private Component componentToBePrinted;
public static void printComponent(Component c) {
new PrintUtilities(c).print();
}
public PrintUtilities(Component componentToBePrinted) {
this.componentToBePrinted = componentToBePrinted;
}
public void print() {
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(this);
if (printJob.printDialog())
try {
printJob.print();
} catch(PrinterException e) {
System.out.println("Error printing: " + e);
}
}
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
if (pageIndex > 0) {
return(NO_SUCH_PAGE);
} else {
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
disableDoubleBuffering(componentToBePrinted);
componentToBePrinted.paint(g2d);
enableDoubleBuffering(componentToBePrinted);
return(PAGE_EXISTS);
}
}
public static void disableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(false);
}
public static void enableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(true);
}
}
by this call PrintUtilities.printComponent(this) in button action listener
This would seem to be your problem.
This will, technically, print the contents of the entire frame, you only need to print the DrawingPanel.
This is going to require you to make some minor changes to your code so you access the instance of the DrawingPanel from your actionPerformed method...
private DrawingPanel drawingPanel;
public Printing(String Firstname,String LastName,String contactid)
{
super("Print badge");
//...
drawingPanel = new DrawingPanel(Firstname,LastName,contactid);
//...
}
This should no allow you to do something like...
PrintUtilities.printComponent(drawingPanel);
Instead...
You can
define custom clip for the print Graphics to exclude the print button area
OR 2. just hide the button
OR 3. override the button's paintComponent() method where check isPrint flag (if it's false call super it true do nothing).
I need to create a program to draw shapes(user chooses with radio button), and whether or not the shape is filled(user chooses with check box). This is the code I have so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SelectShape extends JFrame implements ItemListener{
private JRadioButton line = new JRadioButton("Line");
private JRadioButton rect = new JRadioButton("Rectangle");
private JRadioButton oval = new JRadioButton("Oval");
private JCheckBox fill = new JCheckBox("Filled");
private FigurePanel fp;
public static void main(String[] args) {
SelectShape frame = new SelectShape();
frame.setTitle("Select Shape");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(400,400);
frame.setVisible(true);
}
public SelectShape() {
JPanel p1 = new JPanel();
p1.add(fp);
fp.setBackground(Color.WHITE);
p1.setSize(200,400);
JPanel p2 = new JPanel();
p2.setLayout(new FlowLayout());
p2.add(line);
p2.add(rect);
p2.add(oval);
p2.add(fill);
add(p2, "South");
line.addItemListener(this);
rect.addItemListener(this);
oval.addItemListener(this);
fill.addItemListener(this);
}
public void ItemStateChanged(ItemEvent e) {
if(rect.isSelected()) {
FigurePanel.dRect();
repaint();
}
else if(oval.isSelected()) {
FigurePanel.dOval();
repaint();
}
else if(line.isSelected()) {
FigurePanel.dLine();
repaint();
}
if(fill.isSelected()) {
FigurePanel.fill();
repaint();
}
else {
FigurePanel.erase();
repaint();
}
}
}
class FigurePanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
public void dLine(Graphics g) {
g.drawLine(10,10,160,10);
}
public void dRect(Graphics g) {
g.drawRect(10,10,150,50);
}
public void dOval(Graphics g) {
g.drawOval(10,10,150,50);
}
public void fill(Graphics g) {
g.setColor(Color.GREEN);
if(rect.isSelected()) {
g.fillRect(10,10,150,50);
}
else if(oval.isSelected()) {
g.fillOval(10,10,150,50);
}
}
public void erase(Graphics g) {
g.setColor(Color.WHITE);
if(rect.isSelected()) {
g.fillRect(10,10,150,50);
}
else if(oval.isSelected()) {
g.fillOval(10,10,150,50);
}
}
}
}
The errors I am getting are illegal start of expression and identifier expected. If I should approach this another way, please tell.
I think you need to go back to basics...
This won't work...
fp.setBackground("white");
Component#setBackground doesn't take a String as a parameter, it takes a Color
All your addItemListener calls arn't going to work, because you've not implement a ItemListener
I'm not sure what it is you hope to achieve by doing this...
#Override
fp.dRect();
But it won't work. #Override is used to indicate that a method was overridden by an ancestor, you are simply calling the method of FigurePanel
Java, like C and C++ is case sensitive;
There is no such class itemEvent...it's ItemEvent
public void ItemStateChanged(itemEvent e) {
There is no such class graphics, it's Graphics
public void paintComponent(graphics g) {
And I'm not even going to try and guess what it is you were hoping to achieve with the following...
public void paintComponent(graphics g) {
super.paintComponent(g);
dLine() {
g.drawLine(10, 10, 160, 10);
}
dRect() {
g.drawRect(10, 10, 150, 50);
}
dOval() {
g.drawOval(10, 10, 150, 50);
}
fill() {
g.setColor(Color.GREEN);
if (rect.isSelected()) {
g.fillRect(10, 10, 150, 50);
} else if (oval.isSelected()) {
g.fillOval(10, 10, 150, 50);
}
}
erase() {
g.setColor(Color.WHITE);
if (rect.isSelected()) {
g.fillRect(10, 10, 150, 50);
} else if (oval.isSelected()) {
g.fillOval(10, 10, 150, 50);
}
}
}
Java doesn't support "inline methods" (or what ever you want to call them) and no, making them methods would also not achieve what you are trying to do...
In fact the one thing you did very well, was to override paintComponent and call super.paintComponent...well done :D !
Updated
I would encourage you to have a read through...
The Java Trails, especially those covering the basics, especially those covering inheritance
Custom Painting
2D Graphics
Updated with possible running example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DrawShapes {
public static void main(String[] args) {
new DrawShapes();
}
public DrawShapes() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DrawPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawPane extends JPanel {
public DrawPane() {
setLayout(new BorderLayout());
RenderPane rp = new RenderPane();
add(new ControlsPane(rp), BorderLayout.NORTH);
add(rp);
}
}
public class ControlsPane extends JPanel {
public ControlsPane(RenderPane rp) {
JRadioButton[] btns = new JRadioButton[4];
btns[0] = new JRadioButton(new LineAction(rp));
btns[1] = new JRadioButton(new RectangleAction(rp));
btns[2] = new JRadioButton(new OvalAction(rp));
btns[3] = new JRadioButton(new ClearAction(rp));
ButtonGroup bg = new ButtonGroup();
for (JRadioButton btn : btns) {
bg.add(btn);
add(btn);
}
}
}
public class RenderPane extends JPanel {
private Shape shape;
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public void setShape(Shape shape) {
this.shape = shape;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (shape != null) {
g2d.setColor(Color.RED);
g2d.draw(shape);
}
g2d.dispose();
}
}
public class LineAction extends AbstractRenderAction {
public LineAction(RenderPane renderPane) {
super(renderPane);
putValue(NAME, "Line");
}
#Override
public Shape getShape() {
return new Line2D.Float(0f, 0f, getRenderPane().getWidth(), getRenderPane().getHeight());
}
}
public class RectangleAction extends AbstractRenderAction {
public RectangleAction(RenderPane renderPane) {
super(renderPane);
putValue(NAME, "Rectangle");
}
#Override
public Shape getShape() {
return new Rectangle2D.Float(10, 10, getRenderPane().getWidth() - 20, getRenderPane().getHeight() - 20);
}
}
public class OvalAction extends AbstractRenderAction {
public OvalAction(RenderPane renderPane) {
super(renderPane);
putValue(NAME, "Oval");
}
#Override
public Shape getShape() {
float radius = Math.min(getRenderPane().getWidth() - 20, getRenderPane().getHeight() - 20);
return new Ellipse2D.Float(10, 10, radius, radius);
}
}
public class ClearAction extends AbstractRenderAction {
public ClearAction(RenderPane renderPane) {
super(renderPane);
putValue(NAME, "Clear");
}
#Override
public Shape getShape() {
return null;
}
}
public abstract class AbstractRenderAction extends AbstractAction {
private RenderPane renderPane;
public AbstractRenderAction(RenderPane renderPane) {
this.renderPane = renderPane;
}
public RenderPane getRenderPane() {
return renderPane;
}
public abstract Shape getShape();
#Override
public void actionPerformed(ActionEvent e) {
getRenderPane().setShape(getShape());
}
}
}
Well, the following is definitely not valid Java code:
dLine() {
g.drawLine(10,10,160,10);
}
The same applies to the following dRect, etc.
I'm not sure exactly what you're trying to achieve with that code. If it is to define a method called dLine, you would do the following instead:
public void dLine(Graphics g) {
g.drawLine(10, 10, 160, 10);
}
I also noticed the following code, which is not currently causing you problems, but it will:
public void ItemStateChanged(itemEvent e) {
This is not capitalized properly, so it will not compile, and you're also not listening to any events, so it will never get called.
There are various other errors in the code, but this should get you started.
I have the following program which has some very strange and unwanted behavior when it runs. Its supposed to have two buttons, "Start" and "Stop, but when I click "Start" another button shows up right below "Start". Here's a print screen of what I'm talking about:
What am I doing wrong and how do I fix this ugly problem?
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class TwoButtonsTest {
JFrame frame;
Timer timer;
boolean isClicked;
public static void main(String[] args) {
TwoButtonsTest test = new TwoButtonsTest();
test.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
JButton startButton = new JButton("Start");
startButton.addActionListener(new StartListener());
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(new StopListener());
final DrawPanel myDraw = new DrawPanel();
frame.getContentPane().add(BorderLayout.CENTER, myDraw);
frame.getContentPane().add(BorderLayout.NORTH, startButton);
frame.getContentPane().add(BorderLayout.SOUTH, stopButton);
frame.setVisible(true);
timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
myDraw.repaint();
}
});
}
class StartListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//needs to be implemented
if(!isClicked) {
}
isClicked = true;
timer.start();
}
}
class StopListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//needs to be implemented
timer.stop();
isClicked = false;
}
}
class DrawPanel extends JPanel {
public void paintComponent(Graphics g) {
int red = (int)(Math.random()*256);
int blue = (int)(Math.random()*256);
int green = (int)(Math.random()*256);
g.setColor(new Color(red, blue, green));
Random rand = new Random();
// following 4 lines make sure the rect stays within the frame
int ht = rand.nextInt(getHeight());
int wd = rand.nextInt(getWidth());
int x = rand.nextInt(getWidth()-wd);
int y = rand.nextInt(getHeight()-ht);
g.fillRect(x,y,wd,ht);
}
} // close inner class
}
Also I'm trying to get the Start button to do two things. One is to of course start the animation but when the Stop button is pressed and I press Start again, I want it to clean the screen so to speak and start the animation again a new. Any tips on that?
You do not call super.paintComponent(Graphics g) in overriden paintComponent(..) method which you should in order to honor the paint chain and thus the painting of other components.
This call should also be the first call within the method:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//do painting here
}
A probem might arise that drawings are not persistent. You must than have a way to store drawings and redraw every time. The most common is an ArrayList which will hold objects to be drawn (thus you cann add to the list remove etc), you would than iterate over the list and redraw each object in paintComponent. See my answer here for an example.
Also please remember to create and manipulate Swing components on Event Dispatch Thread :
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//create UI and components here
}
});
Dont call setSize(..) on JFrame rather override getPreferredSize() of JPanel and return an appropriate height which fits all components, than call JFrame#pack() before setting JFrame visible (but after adding all components).
No need for getContentPane().add(..) as of Java 6+ add(..) defaults to contentPane
Do not re declare Random i.e Random r=new Random() each time paintComponent is called as this will make the distributions of the values less random rather initiate it once when class is created and call methods on the instance
Here is the fixed code (with above fixes implemented):
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class TwoButtonsTest {
JFrame frame;
Timer timer;
boolean isClicked;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TwoButtonsTest test = new TwoButtonsTest();
test.go();
}
});
}
final DrawPanel myDraw = new DrawPanel();
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton startButton = new JButton("Start");
startButton.addActionListener(new StartListener());
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(new StopListener());
frame.add(myDraw, BorderLayout.CENTER);
frame.add(startButton, BorderLayout.NORTH);
frame.add(stopButton, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
myDraw.repaint();
}
});
}
class StartListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
//needs to be implemented
if (!isClicked) {
}
myDraw.clearRects();
isClicked = true;
timer.start();
}
}
class StopListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//needs to be implemented
timer.stop();
isClicked = false;
}
}
class DrawPanel extends JPanel {
private ArrayList<MyRectangle> rects = new ArrayList<>();
private Random rand = new Random();
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
addRect();
for (MyRectangle r : rects) {
g.setColor(r.getColor());
g.fillRect(r.x, r.y, r.width, r.height);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public void clearRects() {
rects.clear();
}
public void addRect() {
// following 4 lines make sure the rect stays within the frame
int ht = rand.nextInt(getHeight());
int wd = rand.nextInt(getWidth());
int x = rand.nextInt(getWidth() - wd);
int y = rand.nextInt(getHeight() - ht);
int red = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
rects.add(new MyRectangle(x, y, wd, ht, new Color(red, blue, green)));
}
} // close inner class
}
class MyRectangle extends Rectangle {
Color color;
public MyRectangle(int x, int y, int w, int h, Color c) {
super(x, y, w, h);
this.color = c;
}
public Color getColor() {
return color;
}
}
I wish I could offer a solution, but as of yet I haven't found one. I can tell you the root of the "problem" here lies in the way you are drawing the Center section of your BorderLayout. You are overriding the whole paintComponent() function for this program and having whatever it creates put into the Center of your BoarderLayout. In this case, each time you click a button, the program calls the repaint to draw the image of a clicked button, but since you have also added ANY of the drawn objects to the Center panel, it also is drawn there. Since this specific repaint doesn't specify a location, it goes in the upper left corner.
I fixed your button problem on my Windows XP computer by invoking SwingUtilities.
I formatted your Java code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class TwoButtonsTest implements Runnable {
JFrame frame;
Timer timer;
boolean isClicked;
public static void main(String[] args) {
SwingUtilities.invokeLater(new TwoButtonsTest());
}
#Override
public void run() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
JButton startButton = new JButton("Start");
startButton.addActionListener(new StartListener());
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(new StopListener());
final DrawPanel myDraw = new DrawPanel();
frame.getContentPane().add(BorderLayout.CENTER, myDraw);
frame.getContentPane().add(BorderLayout.NORTH, startButton);
frame.getContentPane().add(BorderLayout.SOUTH, stopButton);
frame.setVisible(true);
timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
myDraw.repaint();
}
});
}
class StartListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// needs to be implemented
if (!isClicked) {
}
isClicked = true;
timer.start();
}
}
class StopListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// needs to be implemented
timer.stop();
isClicked = false;
}
}
class DrawPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
int red = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
g.setColor(new Color(red, blue, green));
Random rand = new Random();
// following 4 lines make sure the rect stays within the frame
int ht = rand.nextInt(getHeight());
int wd = rand.nextInt(getWidth());
int x = rand.nextInt(getWidth() - wd);
int y = rand.nextInt(getHeight() - ht);
g.fillRect(x, y, wd, ht);
}
} // close inner class
}
To clean the screen when you press the Start button, you're going to have to add some methods to your DrawPanel class.
Here's one way to do it.
class DrawPanel extends JPanel {
protected boolean eraseCanvas;
public void setEraseCanvas(boolean eraseCanvas) {
this.eraseCanvas = eraseCanvas;
}
#Override
public void paintComponent(Graphics g) {
if (eraseCanvas) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
} else {
int red = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
g.setColor(new Color(red, blue, green));
Random rand = new Random();
// following 4 lines make sure the rect stays within the frame
int ht = rand.nextInt(getHeight());
int wd = rand.nextInt(getWidth());
int x = rand.nextInt(getWidth() - wd);
int y = rand.nextInt(getHeight() - ht);
g.fillRect(x, y, wd, ht);
}
}
} // close inner class