Draw in a second Java Applet Window - java

i am trying for days to add a second window to my applet in which i want to draw mathematical graphs. Getting the second window is no problem, but i can't get the drawing to work. Maybe you can help me. This is my latest try:
import java.awt.*;
public class FFrame extends Frame{
public FFrame(){
Panel p = new MyPanel();
add(p);
}
private class MyPanel extends Panel {
protected void paintComponent(Graphics g) {
super.paintComponents(g);
g.setColor(Color.WHITE);
g.drawLine(10, 10, 100, 100);
}
};
}
I add this to my applet by creating a new FFrame-Object "f" and run f.show() in the init() method. I don't use swing, by the way.

Related

Cannot get an Oval to Display

I'm new here. Been reading questions and answers for aeons. Recently I found time to start studying Java, and I'm seriously enjoying the process. Until I started to write some code. The getting stuck is killing me. So I've come to seek advice on something extremely simple but I cannot crack it.
The code below attempts to create a frame, maximize it, and place elements inside. I was just fooling around. First the button1, I tried to change its size (so I got it into a FlowLayout). Then a button in the mainPanel, just to... try. Then an oval. I tried for 2 hours to get the oval to display but it is Impossible. When I found about "drawOval" I thought that was it but it made no difference. And to think that I was planning for the button1 to create Moving Balls. I'm so, So far away from that.
Please, why does the silly Oval refuse to display itself. Help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainClass {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JPanel southPanel = new JPanel();
JButton button1 = new JButton("Button1");
JButton button2 = new JButton("Button2");
Oval oval = new Oval();
public static void main(String[] args) {
MainClass program = new MainClass();
program.go();
}
public void go() {
buildGUI();
}
public void buildGUI() {
button1.setBorder(BorderFactory.createMatteBorder(2,2,2,2, Color.BLACK));
button1.addActionListener(new Button1Listener());
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
button1.setPreferredSize(new Dimension(200, 50));
frame.getContentPane().add(BorderLayout.SOUTH, southPanel);
southPanel.add(button1);
mainPanel.add(button2);
mainPanel.add(oval);
frame.setSize(400, 400);
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class Button1Listener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
//What the button will do.
}
}
}
And the Oval part
import java.awt.*;
import javax.swing.*;
public class Oval extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.orange);
g.fillOval(20, 50, 100, 100);
}
}
JPanel uses a FlowLayout by default. Since you Oval class doesn't provide any sizing hints, then it's set to a default size of 0x0.
Start by updating your class to something more like...
public class Oval extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 150);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.orange);
g.fillOval(20, 50, 100, 100);
}
}
to create Moving Balls.
Ok, you might want to have a look at:
java bounceBall mouse escape
paintComponent not working

What did super.paintComponent(g) do?

So in the past few days I've tried to implement an easier version of a graph plotter.
One big problem I was confronted with was a bug that occured on repainting.
Basically I've designed my program in one class which is responsible for drawing the whole coordinate system and the given function after clicking a JButton in an other class. The other class contains the JButton which is pressed. After pressing the JButton it calls a function in the coordinate system class which repaints the picture. Both of those classes are extending JPanel.
The bug was that when I was doing the repainting on pressing the button, the button was drawn on the coordinate System and not in its original place, so in other words on the other JPanel even though I didn't change a thing about placements and stuff. Both classes were added to a JFrame which use a GridLayout.
Can anyone tell me why super.paintComponent(g); solved that bug?
Edit: Added Code
Window class
public class main {
public static void main(String[] args) throws SemanticFailureException {
int x = 800;
int y = 600;
JFrame frame = new JFrame();
frame.setLayout(new GridLayout());
frame.setTitle("Function plotter");
frame.setSize(2*x, 2*y);
Surface test = new Surface(x, y, 10);
CommandDraw test1 = new CommandDraw(x/2,y,test);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(test);
frame.add(test1);
frame.setVisible(true);
}
}
Coordinate System class: (changed drawing the coordinate system to a rectangle for simplicity, the bug still occures with only drawing a rectangle)
public class Surface extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
boolean drawFunct;
public Surface(int x1, int y1, int coordLength) {
setSize(x1,y1);
drawFunct = false;
}
public void paintComponent(Graphics g) {
super.paintComponent(g); // without this the jbutton occures on the left
// create Graphics object to get more functions
Graphics2D g2 = (Graphics2D) g;
// draw Plotter
drawFunction(g2);
if (drawFunct)
g2.drawLine(0, 0, 80, 80);
}
public void drawFunction(Graphics2D g) {
g.drawRect(40, 40, 30, 30);
}
public void redraw() {
drawFunct = true;
repaint();
}
}
The Class with the JButton:
public class CommandDraw extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
JButton makeDraw;
JTextField inputPoly;
Surface surf;
public CommandDraw(int x, int y, Surface surf) {
this.surf = surf;
setSize(x,y);
setLayout(new FlowLayout());
makeDraw = new JButton("draw Function");
makeDraw.setBackground(Color.LIGHT_GRAY);
makeDraw.setFocusable(false);
makeDraw.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
surf.redraw();
}
});
add(makeDraw);
inputPoly = new JTextField("Input polynomial");
inputPoly.setHorizontalAlignment(JTextField.CENTER);
add(inputPoly);
}
}
Can anyone tell me why super.paintComponent(g); solved that bug?
Because the call to paintComponent(g) of the superclass (JPanel) will guarantee that panel will be rendered as expected before you do your paint operations. You need to make sure that your JPanel will behave, in the Graphics perspective, like any other JPanel.
A template for a customized JPanel to draw should be something like:
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class MyDrawPanel extends JPanel {
#Override
protected void paintComponent( Graphics g ) {
super.paintComponent( g );
// create a new graphics context based on the original one
Graphics2D g2d = (Graphics2D) g.create();
// draw whatever you want...
g2d.dispose();
}
}
EDIT
You need to call super.paintComponent(g) to tell that the JPanel paintComponent(Graphics) version should be execute before you start doind your customized things. It's something like to ask the JPanel to prepare its paint capabilities to be used. A good starting point to these kind of doubts is the documentation: https://docs.oracle.com/javase/10/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics)
The dispose() method is being called in the copy of the original Graphics. If you dispose the Graphics that is passed to the method, you may have some issues too. You could use the original Graphics to perform you painting operations, but you shouldn't, so a better practice is to make a copy of the original Graphics and dispose it after using.
Take a look here too: How does paintComponent work?

paintComponent() in Java is not being called [duplicate]

This question already has answers here:
Swing - paintComponent method not being called
(2 answers)
Closed 5 years ago.
I am trying to draw a simple rectangle but I think the paintComponent method is not getting called.
Here is the code for the class with main method:
package painting;
import java.awt.*;
import javax.swing.*;
public class Painting {
public static void main(String[] args) {
JFrame jf;
jf = new JFrame("JUST DRAW A RECTANGLE");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(null);
jf.setLocationRelativeTo(null);
jf.setSize(600,600);
jf.setVisible(true);
Mainting maint = new Mainting();
jf.add(maint);
}
}
and the class with paintComponent()
package painting;
import java.awt.*;
import javax.swing.*;
public class Mainting extends JPanel {
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawRect(0, 0 , 200, 200);
System.out.println("haha");
g.setColor(Color.red);
}
}
What is the problem here, I cannot figure out...
While the answers already provided might have resulted in the rectangle appearing, the approach was less than optimal. This example aims to show a better approach. Read the comments in the code for details.
Note that Swing/AWT GUIs should be started on the EDT. This is left as an exercise for the reader.
import java.awt.*;
import javax.swing.*;
public class Painting {
public static void main(String[] args) {
JFrame jf = new JFrame("JUST DRAW A RECTANGLE");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// null layouts cause more problems than they solve. DO NOT USE!
//jf.setLayout(null);
jf.setLocationRelativeTo(null);
/* if components return a sensible preferred size,
it's better to add them, then pack */
//jf.setSize(600, 600);
//jf.setVisible(true); // as mentioned, this should be last
Mainting maint = new Mainting();
jf.add(maint);
jf.pack(); // makes the GUI the size it NEEDS to be
jf.setVisible(true);
}
}
class Mainting extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(10, 10, 200, 200);
System.out.println("paintComponent called");
/* This does nothing useful, since nothing is painted
before the Graphics instance goes out of scope! */
//g.setColor(Color.red);
}
#Override
public Dimension getPreferredSize() {
// Provide hints to the layout manager!
return new Dimension(220, 220);
}
}
Try setting your layout manager to eg. BorderLayout
so use
jf.setLayout(new BorderLayout());
and then add your component with some constraints
Mainting maint = new Mainting();
jf.add(maint,BorderLayout.CENTER);

Java: How to draw in a canvas?

I'm new to Java and I want to make a simple game where there are squares in a simple grid (something between a snake and a labyrinth). The number of squares doesn't change, only their color does.
I already programmed the objects I need for the game. Now I want to display the game.
I know how to create a JFrame, a JPanel and a JButton, which I will need, but I don't understand how to draw in a canvas.
I made a test class:
import javax.swing.*;
import java.awt.*;
public class Test extends Canvas {
public static void main (String[] arg) {
JFrame f=new JFrame();
f.setTitle("Title");
f.setSize(400,500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
JPanel pan=new JPanel(new FlowLayout());
pan.add(new JButton("hey"));
Test canvas=new Test();
Graphics g=canvas.getGraphics();
canvas.paint(g);
pan.add(canvas);
f.setContentPane(pan);
}
public Test() {
setBackground (Color.green);
setSize(300,300);
setVisible(true);
}
public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.fillRect(10,10,80,80);
g.setColor(Color.BLUE);
g.fillRect(150,50,80,80);
g.setColor(c);
}
}
When I run this, a windows is created, with the correct title , size and button, but there isn't anything else (no green background, no red or blue rectangle), and an error is detected :
Exception in thread "main" java.lang.NullPointerException
at Test.paint(Test.java:25)
at Test.main(Test.java:15)
What am I doing wrong ? Is there a better way to draw these squares ?
Thanks !
Comment these two lines
//Graphics g=canvas.getGraphics();
//canvas.paint(g);
And change the paint method as follows.
#Override
public void paint(Graphics g) {
super.paint(g);
Rest is all fine. Hope it helps you to progress.

How to change/edit a JPanel object at startup/init

I want to change a JPanel-object in an applet at startup/init. I can't figure out how to do this. I've made a simple example of my problem in which I clear the JPanel. It does not work when it is called by the init() method but it works when I press the button. What can I do to change the JPanel at startup/init?
import javax.swing.JApplet;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class TestStartUpApplet extends JApplet {
JPanel panel;
#Override
public void init() {
System.out.println("Init");
erasePanel();
}
private void erasePanel() {
Graphics g = panel.getGraphics();
g.clearRect(0, 0, 117, 48);
}
public TestStartUpApplet() {
getContentPane().setLayout(null);
panel = new JPanel();
panel.setBackground(Color.RED);
panel.setBounds(35, 36, 117, 48);
getContentPane().add(panel);
JButton btnTest = new JButton("Test");
btnTest.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
erasePanel();
}
});
btnTest.setBounds(35, 108, 117, 25);
getContentPane().add(btnTest);
}
}
Works just for me:
public class AppletPaintTest extends JApplet {
#Override
public void init() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
setLayout(new BorderLayout());
ImagePane pane = new ImagePane();
pane.setBackground(Color.RED);
pane.setOpaque(false); // Little trick
add(pane);
}
});
}
#Override
public void start() {
super.start();
}
public class ImagePane extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
Insets insets = getInsets();
int x = insets.left;
int y = insets.top;
int width = getWidth() - 1 - (insets.left + insets.right);
int height = getHeight() - 2 - (insets.top + insets.bottom);
g2d.setColor(getBackground());
g2d.fillRect(x + 10, y + 10, width - 20, height - 20);
g2d.dispose();
}
}
}
question
no idea why do you want to clear empty JPanel without any custom painting
what's wrong with JPanel with red Background
you clear JApplet before became visible on the screen
doesn't works correctly, because doesn't works anything
suggestions
don't use AbsoluteLayout, use LayoutManager instead
Graphics g = panel.getGraphics(); is usefull for printing to the printer, or save Graphics to the image, don't use this method for another reason
read how JApplet works
maybe to use JFrame in the case that you don't want to publish your GUI to the web browser
maybe to read tutorial about 2D Graphics
Whenever you do any custom painting outside of the usually system calls to your paint() or paintComponent() methods, you must call invalidate() on any components you wish to repaint. So for your erasePanel() method, I would suggest setting some flag then calling panel.invalidate(). Then inside your panel's paintComponent() method, you can check the flag to see if you need to draw the introductory picture or just leave the panel blank.
Ok, it seems that the problem was that my coding was just bad. I wanted to change a panel object by a method from another class and that's not the way to do it. I rewrote my code and made a panel class in which the painting is done using paintcomponent. I now use objects of this panel class and it shows the graphics I want at startup.
Thanks for the help!

Categories

Resources