Cannot get an Oval to Display - java

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

Related

How can I make painted graphics in a JPanel scrollable?

I am making an adaptation of a board game. The board will be drawn on a JPanel by overriding the paintComponent(Graphics g) method. The board can possibly be larger than the size of the JPanel it is drawn in, so I planned to use a JScrollPane to allow the user to scroll across the board to view it. As an example, I made the board a single large rectangle to see if I could get it to scroll across that, but to no avail. I have used JScrollPane successfully before but I cannot figure out why this case is any different from the way I previously used it.
Can anyone see why it is not working correctly?
Here is the code for the Game's JFrame:
public class GameFrame extends JFrame{
JPanel playerDeckPanel, contentPane;
JScrollPane gameScrollPane;
BoardPanel boardPanel;
public GameFrame(){
super();
SwingUtilities.invokeLater(new Runnable(){
public void run(){
boardPanel = new BoardPanel();
playerDeckPanel = new JPanel();
boardPanel.setLayout(new GridLayout(1,1));
playerDeckPanel.setLayout(new CardLayout());
boardPanel.setSize(1000,1000);
gameScrollPane = new JScrollPane(boardPanel);
gameScrollPane.setPreferredSize(new Dimension(300,300));
contentPane = ((JPanel) getContentPane());
contentPane.setLayout(new GridLayout(1,2));
contentPane.add(gameScrollPane);
contentPane.add(playerDeckPanel);
setMinimumSize(new Dimension(800,600));
}
});
}
public static void main(String[] args){
GameFrame gameFrame = new GameFrame();
gameFrame.setVisible(true);
}
private class BoardPanel extends JPanel{
public BoardPanel(){
super();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(100, 10, 700, 600);
revalidate();
}
}
}
This is my first time posting a question, so let me know if you need additional information to solve this problem
You need to setPreferredSize on BoardPanel, that seems to do the trick. Don't ask why ;-)
-#geert3

Rectangle not showing up

Nothing happens on pressing the Button, what I am doing wrong?? I want the Rectangle to be drawn on pressing the button. What's wrong with the code??
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
class rectangle{
public static void main(String args[]){
EventQueue.invokeLater(new Runnable(){
public void run(){
final JFrame frame=new JFrame("RECTANGLE");
final JPanel panel=new JPanel();
JButton button=new JButton("DRAW");
panel.add(button);
frame.add(panel);
frame.setSize(400,400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
panel.add(new drawrectangle());
}
});
}
});
}
}
class drawrectangle extends JComponent{
public void paintComponent(Graphics g){
Graphics2D g2=(Graphics2D) g;
g2.setPaint(Color.PINK);
Rectangle2D rect=new Rectangle2D.Double(50,50,200,200);
g2.draw(rect);
g2.fill(rect);
}
}
You need to call repaint() on your JFrame.
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
drawrectangle rec= new drawrectangle();
panel.add(rec);
rec.paintComponent();
frame.repaint();
}
});
Simply write :
frame.validate();
frame.repaint();
Your component has no size. You need to either override getPreferredSize() and return the size of your rectangle, or else you need to set its size in its constructor by calling setSize(). The reason your rectangle doesn't appear is because it is drawing outside of its area, and the Java 2D graphics are clipping the portion you are drawing outside the component (that is, all of it).
It is not the case that you need to either call repaint() or validate() because when you add the rectangle to the panel, it will automatically lay itself out again and mark itself as needing a repaint.
However, be aware that you are adding a new rectangle every time the event fires. Is that what you want? Also, rectangle and drawrectangle should begin with capital letters to conform to the normal Java naming conventions, although there is also a java.awt.Rectangle class, so Rectangle might not be the best name to use.
Just add window.visibility to true.

draw rectangle in Jpanel

I am trying to get my hands on GUI programming in java and wanted to draw a rectangle in Jpanel. Code does not give any error but I cannot get rectangle in the GUI. Can somebody please tell me what I am missing in the following code. I am sure it is pretty simple so please be gentle.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloWorldGUI2 {
private static class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
private static class RectDraw extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(230,80,10,10);
g.setColor(Color.RED);
g.fillRect(230,80,10,10);
}
}
public static void main(String[] args) {
JPanel content = new JPanel();
RectDraw newrect= new RectDraw();
JButton okButton= new JButton("OK");
JButton clearButton= new JButton("Clear");
ButtonHandler listener= new ButtonHandler();
okButton.addActionListener(listener);
clearButton.addActionListener(listener);
content.add(okButton);
content.add(clearButton);
content.add(newrect);
JFrame window = new JFrame("GUI Test");
window.setContentPane(content);
window.setSize(250,100);
window.setLocation(100,100);
window.setVisible(true);
}
}
Your newrect RectDraw's size is likely going to be quite small, probably [0, 0], since it has been added to a FlowLayout using JPanel and doesn't have a preferredSize set. Consider overriding its getPreferredSize() method and returning a suitable Dimension so that its drawing can be seen.
private static class RectDraw extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(230,80,10,10);
g.setColor(Color.RED);
g.fillRect(230,80,10,10);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H); // appropriate constants
}
}
Also,
The paintComponent method should be protected, not public
Don't forget to use #Override before your method overrides.
Aim for much less code in the main method and more code in the "instance" world, not the static world.
Take care with your code formatting. Poor code formatting, especially misleading indentations, leads to silly errors.

Java - paintComponent won't show drawings on JPanel

I've gotten stuck trying to draw on a JPanel. I've learned how to create a JFrame, a JPanel, add event handlers, do the same in applets, and some other basic GUI development. But everytime I try to draw on a JPanel using the paintComponent(Graphics g) or paint(Graphics g) methods, nothing shows up. Buttons, as well as other JComponents, show up just fine. But g.drawString, g.drawRect, etc result in a blank JFrame window.
Here is my code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class Game extends JPanel {
public static void main(String[] args) {
new Game().game();
}
JPanel panel;
JButton button2;
JButton button;
public void game() {
panel = new JPanel();
button = new JButton("Ok");
panel.setLayout(new FlowLayout());
panel.add(button);
button2 = new JButton("Cancel");
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setResizable(false);
frame.add(panel);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("hi",100,100);
g.fillRect(100,50,200,300)
}
}
The JPanel you're adding to your JFrame is a plain vanilla JPanel, not an instance of Game, your custom class that contains the paintComponent() method. YOu need to change that one line to
JPanel panel = new Game();
and you should see a difference immediately!
The instance of Game you create in main() isn't being used for anything, other than calling the game() method. You could use it, if you wanted, by doing this instead:
JPanel panel = this;
and then proceeding as before.

JButton and JLabel dissappears when adding custom background

JButton and JLabel disappears when adding custom background. I don't see any problems in my program, but maybe you guys find an solution! I think it's only a little thing I forgot, but I can't figure it out.
Here's the code:
GameWindow.java:
setContentPane(new StartImagePanel(RollrackLogo));
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
The background appears perfect, but not the JButton and JLabel!
Code to the StartImagePanel.java:
public class StartImagePanel extends JComponent{
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
Your button and label are added to your GameWindow frame while they should be added to its contentPane, setContentPane(new StartImagePanel(RollrackLogo)); instead. That's why they are not showing, they are added to the frame.
Make a variable of the StartImagePanel and add the button and label to it and they should show up.
StartImagePanel contentPanel = new StartImagePanel(RollrackLogo);
setContentPane(contentPanel);
...
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
contentPanel.add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
contentPanel.add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
Answer dispute
The claims in the first paragraph are plain wrong. Here is source that proves it.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class AddToCustomContentPane {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new FlowLayout());
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.setBackground(Color.RED);
JFrame f = new JFrame("Demo");
f.setContentPane(gui);
// Acid test. Can we add buttons direct to the frame?
f.add(new JButton("Button 1"));
f.add(new JButton("Button 2"));
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
Edit after the custom panel code was given
Here's a snippet that works to show both button and label on a black image background, I removed that was not needed (listeners).
public static void main(String[] v) {
class StartImagePanel extends JPanel {
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
class GameWindow extends JFrame{
public GameWindow() {
BufferedImage RollrackLogo;
RollrackLogo = new BufferedImage(400,200,BufferedImage.TYPE_INT_RGB);
final JButton JBRandom = new JButton();
final JLabel JLWelcome = new JLabel();
setDefaultCloseOperation(EXIT_ON_CLOSE);
StartImagePanel panel = new StartImagePanel(RollrackLogo);
setContentPane(panel);
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
JLWelcome.setText("Welcome to Rollrack");
panel.add(JLWelcome);
JLWelcome.setVisible(true);
JBRandom.setText("Random");
panel.add(JBRandom);
JBRandom.setVisible(true);
}
}
GameWindow window = new GameWindow();
window.pack();
window.setVisible(true);
}
I rather use an instance of a JFrame, instead of extending it, as #Andrew Thompson suggested in another question.
However, if you're extending it, it might be a good practice to call super() in the constructor.
Additionally, we may need to know what is going on in your StartImagePanel.
It seems, to me, to be the problem.
Ensure both your GameWindow and StartImagePanel extend properly their superclasses (call super();).
Ensure your StartImagePanel has a proper Layout.
Add your components before you set your frame visible. This also means you won't need JLWelcome.setVisible(true);.
Ensure that your code is executed in the EDT (Event-Dispatch Thread).
Example:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class GameWindow extends JFrame{
BufferedImage rollrackLogo;
JButton jbRandom;
JLabel jlWelcome;
public GameWindow() {
super();
jbRandom = new JButton("Random");
jlWelcome = new JLabel("Welcome to Rollrack, " +
namewindow.name);
rollrackLogo = new BufferedImage(400, 200,
BufferedImage.TYPE_INT_RGB);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setContentPane(new StartImagePanel(rollrackLogo));
// Add your components.
add(jlWelcome);
add(jbRandom);
addKeyListener(new KeyListener() {
#SuppressWarnings("static-access")
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == e.VK_ESCAPE){
System.exit(7);
}
}
#Override
public void keyReleased(KeyEvent arg0) {}
#Override
public void keyTyped(KeyEvent arg0) {}
});
// Pack, or otherwise set fullscreen.
pack();
// Now, set frame visible.
setVisible(true);
}
}
Edit: Now that you've posted the code for your StartImagePanel, I see that you're extending JComponent. Follow my previous advice, (call super), set a Layout, and extend JPanel instead.

Categories

Resources