How to draw shapes from a class to an applet? - java

total programming beginner here, trying to learn some Java over school holidays. Been making simple things and have started looking at GUIs and drawing shapes using Graphics. I've mostly been following tutorials and heaps of answers posted here.
I'm having trouble drawing shapes from my Draw class into my DrawTest applet; as below
import java.awt.*;
import java.applet.*;
import javax.swing.*;
public class DrawTest extends Applet
{
Draw circle = new Draw();
public void init()
{
Panel mainPanel = new Panel();
mainPanel.setLayout(new GridLayout(0,2)); //a left and right panel
JPanel drawPanel = new JPanel(); //left panel to draw shapes into
drawPanel.setBackground(Color.BLACK);
JLabel headerLabel = new JLabel("Draw shapes from another class");
headerLabel.setForeground(Color.GREEN);
drawPanel.add(headerLabel);
drawPanel.add(circle);
circle.drawing();
JPanel textPanel = new JPanel(); //right panel for text
TextArea output = new TextArea("Circle and oval");
textPanel.add(output);
mainPanel.add(drawPanel);
mainPanel.add(textPanel);
add(mainPanel);
}
}
And the Draw class
import java.awt.*;
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.*;
public class Draw extends JPanel
{
public void drawing()
{
repaint();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
// a circle (int x, int y, int width, int height,int startAngle, int arcAngle);
g.fillArc(20,20,50,50,0,360);
//this will draw a oval of width 60 & height 40 at (10,30)
g.setColor(Color.RED);
g.drawOval(10,30,60,40);
}
}
Thanks in advance for any pointers.

You have that problems because you use swing and awt components together. Use only swing components.
Use JApplet instead of Applet.
Use JPanel instead of Panel.
Use JTextArea instead of TextArea.
Also wrap JtextArea with JSrollPane, and as mentioned by dehlen you needn't drawing() method.
For example change your init() method like next :
public void init() {
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(0, 2)); // a left and right panel
JPanel drawPanel = new JPanel(new BorderLayout());
drawPanel.setBackground(Color.BLACK);
JLabel headerLabel = new JLabel("Draw shapes from another class");
headerLabel.setForeground(Color.GREEN);
drawPanel.add(headerLabel,BorderLayout.EAST);
circle.setBackground(Color.BLACK);
drawPanel.add(circle);
JPanel textPanel = new JPanel(new BorderLayout()); // right panel for text
JTextArea output = new JTextArea("Circle and oval");
textPanel.add(new JScrollPane(output));
mainPanel.add(drawPanel);
mainPanel.add(textPanel);
add(mainPanel);
setSize(600,200);
}

First of all you are mixing awt and swing components. Please type JTextArea and JPanel and JApplet instead of TextArea, Applet and Panel. Also you might want to do something like this:
JPanel drawPanel = new Draw();
but your solution should work too. Again i think your problem occurs because of mixing awt and swing components.
Also the circle.drawing(); is unnecessary since the panel calls paintComponent() when initializing.

Related

How do you make it so that a button doesn't interfere with the location of drawn shape?

So basically when I add a button it essentially pushes the black rectangle drawn in this program down, putting it out of its given location. How would you fix this?
import javax.swing.*;
import java.awt.*;
public class Grid {
public class homeGraphics extends JComponent {
homeGraphics() {
setPreferredSize(new Dimension(450, 600));
}
public void paint(Graphics g) {
super.paint(g);
g.fillRect(200, 275, 50, 50);
}
}
public void homeFrame() {
JFrame frame1 = new JFrame();
frame1.setSize(450, 600);
frame1.setResizable(false);
frame1.setDefaultCloseOperation(frame1.EXIT_ON_CLOSE);
JButton playButton = new JButton("Play");
playButton.setPreferredSize(new Dimension(60, 30));
JPanel panel1 = new JPanel();
panel1.add(playButton);
panel1.add(new homeGraphics());
frame1.add(panel1);
frame1.setVisible(true);
}
public static void main(String args[]) {
Grid frame = new Grid();
frame.homeFrame();
}
}```
it essentially pushes the black rectangle drawn in this program down, putting it out of its given location.
What do you mean out of its location? Painting is always done relative to the component. So your painting will always be done at (200, 275) of the component.
If you are attempting to paint at (200, 275) relative to the "frame", then don't. That is NOT how painting works.
Other problems with your code:
Don't attempt to set the size of your frame. If the custom panel is (450, 600) how can the frame possibly be the same size? The frame also contains the "title bar" and "borders". Instead of using setSize(), you invoke frame.pack()just beforeframe1.setVisible(….)`.
Class names start with an upper case character. Learn by example. Have you ever seen a class name in the JDK that doesn't start with an upper case character?
Custom painting is done by overriding paintComponent(…), not paint().
By default a JPanel uses a FlowLayout. So what you see it the button on one line and then the "HomeGraphics" class is too big to fit on the same line so it wraps the to the second line.
You should be more explicit when you do frame layout. So your code should be something like:
JPanel wrapper = new JPanel();
wrapper.add( playButton );
//JPanel panel1 = new JPanel();
//panel1.add(playButton);
//panel1.add(new homeGraphics());
JPanel panel1 = new JPanel( new BorderLayout() );
panel1.add(wrapper, BorderLayout.PAGE_START);
panel1.add(new HomeGraphics(), BorderLayout.CENTER);
Now the code shows your layout attempt more clearly.

Adding a canvas to a panel doesn't show the canvas?

First of all: sorry, if this question was asked before, but I cannot seem to find an answer anywhere, so here we go:
I am trying to get a canvas element to show while it being added to a panel with a titled border around the panel. Here is my code.
public class TestClass extends JFrame{
private TestClass() {
GuiCanvas canvas = new GuiCanvas();
setTitle("TestClass");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1300, 800);
Border menuBorder = BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.LIGHT_GRAY), "Overview");
JPanel controlpanel = new JPanel();
JPanel panelCanvas = new JPanel();
panelCanvas.setBorder(menuBorder);
panelCanvas.add(canvas);
controlpanel.setLayout(new GridLayout(3, 1));
controlpanel.add(panelCanvas);
add(controlpanel);
setLocationRelativeTo(null);
setVisible(true);
System.out.println(canvas.getBounds());
}
private class GuiCanvas extends Canvas {
GuiCanvas() {
setBackground(Color.LIGHT_GRAY);
}
#Override
public void paint(Graphics g) {
g.drawLine(20, 20, 20, 200);
}
}
public static void main(String[] args) {
new TestClass();
}
}
The above code results in an empty panel with a titled border when it should show the defined line I draw in the GuiCanvas-Class. Am I missing something here? Is it even possible to add a canvas-element to a panel? Thanks for your help in advance :)
If you want the canvas to stretch to the size of the panel, change:
JPanel panelCanvas = new JPanel();
To:
JPanel panelCanvas = new JPanel(new GridLayout());
See also this answer:
It is indeed possible to add a Canvas object to a JPanel.
Your problem lies in the fact that your Canvas has no defined size.
What you need are the two following lines
canvas.setPreferredSize(new Dimension(1300,300));
/*
*
*/
this.pack();
This will place your canvas inside the panelCanvas border, displaying a black vertical line on a light gray background.

Weird Swing Glitch?

I don't understand this, I'm currently making a main menu for a game i'm making but for some reason when I hover over a JButton, it flashes up on the top left side of the JFrame. I don't have any mouseAction methods or anything, is it the gif i'm using? I'm not sure...
Here is a screengrab of the error
Here is my code :
import javax.swing.*;
import java.awt.*;
public class MainMenu {
JFrame frame = new JFrame("Frasergatchi");
public void display(){
frame.setSize(400,400);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setVisible(true);
}
public void addComponents(){
JButton play = new JButton("Play");
JButton instructions = new JButton("Instructions");
JButton exit = new JButton("Exit");
JPanel panel = new JPanel();
paintMenu paintMenu = new paintMenu();
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
frame.add(panel);
play.setAlignmentX(Component.CENTER_ALIGNMENT);
instructions.setAlignmentX(Component.CENTER_ALIGNMENT);
exit.setAlignmentX(Component.CENTER_ALIGNMENT);
panel.add(paintMenu);
panel.add(play);
panel.add(instructions);
panel.add(exit);
}
public class paintMenu extends JPanel{
public void paintComponent(Graphics graphics){
Image dog = new ImageIcon(getClass().getResource("DogMenuImage.gif")).getImage();
graphics.drawImage(dog,170,240,this);
}
}
}
The first statement in the paintComponent() method should always be:
super.paintComponent(g);
to make sure the background gets cleared.
Also:
Don't do I/O in a painting method. Painting methods are for painting only. Read the image in the constructor of your class and same the image in an instance variable.
Class names SHOULD start with an upper case character. Think of all the classes in the JDK and follow the standards.
There is no need to create a custom class to paint the image. Just use a JLabel with an Icon.

Drawing to a nested panel using BorderLayout

im new to Java so therefore I am trying out some things.
I am playing around with Java layouts, specfically Nested Panels using BorderLayout.
The Problem that I have is that i am unable to draw to the nested panels. I am able to draw to the main panel but not the panels nested within it.
I would be very greatful if you could show me where I am going wrong.
Here is my main code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUI extends JFrame{
public GUI()
{
setSize(600,600);
Here is the main panel.
JPanel pan1 = new JPanel();
pan1.setLayout(new BorderLayout());
pan1.setPreferredSize(new Dimension(200,200));
JLabel label = new JLabel("Panel 1");
pan1.add(label);
Then i create the two nested panels which i add to the main one.
JPanel pan2 = new JPanel();
pan2.setBackground(Color.YELLOW);
pan2.setPreferredSize(new Dimension(200,200));
JPanel pan3 = new JPanel();
pan3.setBackground(Color.YELLOW);
pan3.setPreferredSize(new Dimension(200,200));
Here is where I call the class which draws the shape on the screen.
draw drawingShape = new draw();
Here is the problem as i am unable to draw the shape to the nested panel.
pan2.add(drawingShape);
However i can draw it to this panel which is the main one.
pan1.add(drawingShape);
I am inserted the two panels to the main one.
pan1.add(pan2, BorderLayout.NORTH);
pan1.add(pan3, BorderLayout.SOUTH);
getContentPane().add(pan1);
setVisible(true);
}
public static void main(String args[])
{
new GUI();
}
}
Here is the code for creating the shape which is completley fine:
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class draw extends JPanel{
public void paint(Graphics g) {
Image img = createImage();
g.drawImage(img, 20,20,this);
}
private Image createImage(){
BufferedImage bufferedImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.getGraphics();
return bufferedImage;
}
}
The code does compile, i appreciate any help.
Regards
Custom painting is done by overriding the paintComponent() method, not the paint() method. Also, don't forget to invoke super.paintComponent().
Read the section from the Swing tutorial on Custom Painting for more information and examples.
Here is the code for creating the shape which is completley fine:
I don't see how it can be fine. As far as I can tell it doesn't do anything. First of all don't create the image in the paintComponent() method. This method gets called whenever Swing determines a component needs to be repainted. Secondly, all the code does is create an blank image.
Read the tutorial and post an actual SSCCE if you still have problems.

JButton absolute underneath my paint() board

I have a poker game where I designed a nice pretty GUI that displays the cards and players. I did it all extending JPanel inside paint() with a lot of g2d.drawImage's and g2d.drawString()'s, with definite x and y locations.
My problem now is that I need to have a couple interactive buttons underneath it.. but whenever I try to add a JButton, it appears top and center. I've used setLocation(x, y) and setLayout(null) and everything I've seen in other replies, but none of them seem to match my need (Or at least I don't have a very well understanding of where to put it)
This is how my code is set up:
pokerserver.java
public class pokerserver extends JFrame {
public pokerserver() {
add(new drawing());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(720, 640);
setLocationRelativeTo(null);
setTitle("Poker HANGOUTS");
setResizable(false);
setVisible(true);
}
public static void main(String args[]) {
new pokerserver();
}
And then in drawing.class
public drawing() {
setFocusable(true);
setBackground(new Color(39,91,46));
setDoubleBuffered(true);
gameCards = new cards();
gameCards.shuffle();
for (int i = 0; i < 10; i++)
seats[i] = -1;
HQ = new HeadQuarters(this);
HQ.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
//All my UI code
}
My last attempt was trying to add
JButton button = new JButton("TEST");
add(button);
button.setLocation(10, 500);
at the end of public drawing(). I Keep seeing things on layout management, but it's not helping me -- mainly because I'm not sure how to implement it
Here's a screenshot to help visualize what I'm talking about->
http://i.imgur.com/ttvif.png
Trying to get the button underneath. Unless there's a way to add an ActionListener to a drawImage()?
For your main panel use a BorderLayout.
Then to the "CENTER" you can add your game panel with all your custom painting.
Then create a panel and add the buttons to it. Now you can add this panel to the NORTH of the main panel.
In other words you are not restricted to using a single panel.
Also, custom painting should be done in the paintComponent() method of your panel, NOT the paint() method.
I'm not really sure what you are after, but here are two interpretations.
I suspect you want the 1st one 'Buttons over custom painting', but as a user I'd prefer the 2nd, with 'Buttons below custom painting'.
import java.awt.image.*;
import java.awt.*;
import javax.swing.*;
class PaintPanel extends JPanel {
BufferedImage bg;
PaintPanel(LayoutManager2 layout) {
super(layout);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg==null) {
bg = new BufferedImage(500,500,BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bg.createGraphics();
GradientPaint gp = new GradientPaint(
0,0,Color.RED,500,500,Color.BLUE);
g2.setPaint(gp);
g2.fillRect(0,0,500,500);
g2.dispose();
}
g.drawImage(bg,0,0,getWidth(),getHeight(),this);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel buttons = new JPanel(
new FlowLayout(FlowLayout.CENTER));
buttons.setOpaque(false);
buttons.add(new JButton("Start"));
buttons.add(new JButton("Stop"));
PaintPanel pp = new PaintPanel(new BorderLayout());
pp.setPreferredSize(new Dimension(200,100));
pp.add(buttons, BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null,pp);
JPanel gui = new JPanel(new BorderLayout());
gui.setBackground(Color.ORANGE);
gui.add(pp, BorderLayout.CENTER);
gui.add(buttons, BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null,gui);
}
});
}
}

Categories