The JFrame and JPanel show up, but the paintComponent method isn't drawing on the JPanel. I only see the JLabel, JTextField and JButton that I added but not what should be drawn on the JPanel.
update; question has been answered: The circles actually were being drawn to the JPanel but I got the coordinates wrong so they were being drawn outside of the frame.
JFrame class:
package h02;
import javax.swing.*;
public class Circles extends JFrame {
public Circles() {
// JFrame and its properties
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.setTitle("Circles");
frame.add(new CirclesPanel());
frame.setVisible(true);
}
public static void main(String[] args) {
new Circles();
}
}
JPanel class:
package h02;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class CirclesPanel extends JPanel implements ActionListener {
// Fields
private JTextField enterDiameter;
private JButton drawButton;
private int diameter;
private final int Y = 470;
// making the panel
public CirclesPanel() {
enterDiameter = new JTextField("100", 5);
enterDiameter.addActionListener(this);
drawButton = new JButton("Teken");
drawButton.addActionListener(this);
add(new JLabel("Diameter"));
add(enterDiameter);
add(drawButton);
}
// find the diameter
public void findDiameter() {
int diameterString = Integer.parseInt(enterDiameter.getText());
diameter = diameterString;
}
// draw circles
public void paintComponent(Graphics g) {
super.paintComponent(g);
int centre = getWidth() / 2;
g.drawLine(30, Y, Y , Y);
g.setColor(Color.ORANGE);
g.fillOval(centre, Y, diameter, diameter);
g.setColor(Color.BLACK);
g.drawOval(centre, Y, diameter, diameter);
g.drawOval(centre, Y, diameter / 2, diameter);
}
// on action performed...
public void actionPerformed(ActionEvent e) {
findDiameter();
repaint();
}
}
The problem is with your "Y" in CirclesPanel. Elements are drawn but outside the frame, try reducing Y, than surely you'll see your elements.
Alternatively increase the frame size.
Related
I need to resize a drawn oval in Java, I created this code for it:
FrameView.java
package tutorial;
import java.awt.*;
import javax.swing.*;
public class FrameView{
public static void main(String args[]){
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BallCreation c = new BallCreation();
f.add(c);
f.setSize(500, 500);
f.setVisible(true);
}
}
BallCreation.java
package tutorial;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BallCreation extends JPanel{
private static final long serialVersionUID = 1L;
private int height = 10;
private int width = 10;
private JPanel panel;
private JButton button1;
public BallCreation(){
panel = new JPanel();
button1 = new JButton("Click");
add(button1);
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
height = height + 2;
width = width + 2;
}
});
}
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(Color.WHITE);
g.setColor(Color.GREEN);
g.fillOval(10, 10, width, height);
}
}
The problem is is that it isn't working, I am not sure how I can make the oval refresh to its new size. I think it should be working, but for some reason the button doesn't parse the new height and width on to the paintComponent.
Just add a repaint() at the end of your actionPerformed method , or you won't see the change (unless you minimize then restore your window for instance, to force a repaint of the area).
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
height = height + 2;
width = width + 2;
repaint();
}
});
I'm trying to make a panel that contains a shape and a button. The issue is that when I add a button to the JPanel, the shape does not appear. It just shows the button on the top of my screen. The square only shows up when add the square to the frame instead of the panel, but the button will not appear.
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel panel = new JPanel();
//Replace FRAME_WIDTH/HEIGHT with a number greater than 100
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Square Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Creates a Red Square from RedSquare
final RedSquare red = new RedSquare();
panel.add(red);
JButton button = new JButton();
button.setText("Red");
panel.add(button);
frame.add(panel);
frame.setVisible(true);
}
public class RedSquare extends JComponent
{
private Square sq;
private int x = 100;
private int y = 0;
private Graphics2D g2;
public RedSquare()
{
sq = new Square(x,y,Color.red);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
sq.draw(g2);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void moveBy()
{
y++;
sq = new Square(x,y,Color.red);
repaint();
}
}
public class Square
{
private int x;
private int y;
private Color color;
public Square(int x, int y, Color color)
{
this.x = x;
this.y = y;
this.color = color;
}
public void draw(Graphics2D g2)
{
Rectangle body = new Rectangle(x, y, 40, 40);
g2.draw(body);
g2.setPaint(color);
g2.fill(body);
g2.draw(body);
}
}
Do I need to do something else to make this work? Am I missing something? I am new to this and any help is greatly appreciated.
I think you have to set layout in panel using panel.setLayout(new FlowLayout()); before adding anything into panel, to make it show your both shapes. As it is overriding right now .
When adding components to a JFrame try using the setContentPane rather than add. So from your example above, remove the frame.add(panel); and use frame.setContentPane(panel);
It is unusual that you are extending JComponent which is abstract - though not prohibited.
One solution is to use JPanel instead of JComponent.
And also setting the x coordinate to x=0 will show you the square.
Beyond that you can use a layout etc:
panel.setLayout(new BorderLayout());
....
panel.add("Center", red);
.......
panel.add("South", button);
To create my first 2D game in Java, I thought of using the JFrame's getContentPane(), updating it with the new view every 50ms.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// ...
frame.setVisible(true);
// ...
Container area = frame.getContentPane();
Graphics pen = area.getGraphics();
pen.clearRect(0, 0, area.getWidth(), area.getHeight()); // Remove previous drawing
pen.drawString("Text", 50, 50);
// ...
area.repaint();
But it doesn't work; the window doesn't change.
As kiheru already said, use paintComponent(Graphics g) for custom painting. Here is an example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Example {
int i = 0;
public Example() {
JFrame frame = new JFrame();
frame.getContentPane().add(new DrawingPanel());
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
ActionListener actionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.getContentPane().repaint();
}
};
Timer timer = new Timer(500, actionListener); //500 = Every 500 milliseconds
timer.start();
}
class DrawingPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // Removes previous graphics
Random r = new Random(); //Randomizer
//Random x- and y-coordinates
int x = r.nextInt(400);
int y = r.nextInt(400);
//Random rgb-values
int red = r.nextInt(255);
int green = r.nextInt(255);
int blue = r.nextInt(255);
//Random width and height
int width = r.nextInt(100);
int height = r.nextInt(100);
g.setColor(new Color(red, green, blue)); //Setting color of the graphics
g.fillRect(x, y, width, height); //Filling a rectangle
}
}
public static void main(String[] args) {
new Example();
}
}
research for double buffering or for fast image drawing using VolatileImage type for directly rending into graphics card. In your case if you use double buffering the code will be:
private static BufferedImage bufferedImage = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
private static Graphics2D gBuff = bufferedImage.createGraphics();
public static void main(String[] args)
{
JFrame frame = new JFrame()
{
#Override
public void paint(Graphics g)
{
g.drawImage(bufferedImage,0,0,this);
}
};
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
gBuff.setColor(Color.WHITE);
gBuff.fillRect(0, 0, frame.getWidth(), frame.getHeight()); // Remove previous drawing
gBuff.setColor(Color.BLACK);
gBuff.drawString("Text", 50, 50);
// ...
frame.setVisible(true);
// ...
}
I'm trying to get JButtons which have been added to a JPanel to show up during the execution of a program, however they only appear when I hover the mouse of them, they remain invisible until then.
Below is my code, I've tried repaint() and revalidate() with no luck.
There also seems to be an issue with the height of the JPanel, it seems to be larger than the main Window for some reason
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public final class SideMenu extends JPanel implements ActionListener{
private final int width;
private final int height;
public SideMenu(int width, int height){
this.width = width;
this.height = height;
this.setLayout(new GridLayout(0,1));
this.add(new JButton("button1"));
this.add(new JButton("button2"));
this.add(new JButton("button3"));
this.revalidate();
this.repaint();
}
#Override
public void paint(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(0, 0, width, height);
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
public static void main(String[] args){
int width = 300, height = 400;
JFrame jf = new JFrame();
jf.setTitle("Fish Tank");
jf.setSize(width, height);
jf.setVisible(true);
jf.setLayout(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
///jf.setResizable(false);
SideMenu side_menu = new SideMenu(100,height);
jf.add(side_menu);
side_menu.setBounds(200, 0, 100, height);
}
}
Use paintComponent(..) method instead of paint(..):
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(0, 0, width, height);
}
Read more about custom paintings.
Also call jf.setVisible(true); at the end of construction of GUI, when you add all components to JFrame.
Right now I am making my jinternal frames transparent using this code:
double rgbConversionBackpack = Double.parseDouble(MyClient.configFile.getProperty("BACKPACK_FRAME_ALPHA"));
double tmp = (rgbConversionBackpack / 100.0) * 255.0;
this.getContentPane().setBackground(new Color(140, 0, 0, (int)tmp));
this.setOpaque(false);
I have code on the sliders to set the alpha which all works perfectly and saves it to a properties file, yada, yada, yada. The question is how do I make the entire JInternal Frame transparent.
Right now I have only be able to set the content pane, and any other panels (etc) that are in the jinternal frames transparent, but I want to make the entire JinternalFrame(borders and all) transparent.
Screenshot below shows how on the backpack the red tinted are is partially transparent and looks decent, but still want the border to be transparent also.
Is there a way to override the draw super method for each of my classes the extend JInternalFrame to have it draw semi transparent(depending on value obviously)?
You could do this by changing the AlphaComposite that the JInternalFrame's paint method uses. You have to be careful though to repaint the containing top level window at the location of the transparent component lest you have funny side effects. For example:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
#SuppressWarnings("serial")
public class TransparentInternalFrame extends JDesktopPane {
private static final Color COLOR_1 = Color.red;
private static final Color COLOR_2 = Color.blue;
private static final float PT_2 = 30f;
private static final int PREF_W = 800;
private static final int PREF_H = 500;
public TransparentInternalFrame() {
add(new MyInternalFrame("Foo", 50, 50, 300, 300, 0.2f));
add(new MyInternalFrame("Foo", 400, 100, 300, 300, 0.4f));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(new GradientPaint(0, 0, COLOR_1, PT_2, PT_2, COLOR_2, true));
g2.fillRect(0, 0, getWidth(), getHeight());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
TransparentInternalFrame mainPanel = new TransparentInternalFrame();
JFrame frame = new JFrame("TransparentInternalFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_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();
}
});
}
}
#SuppressWarnings("serial")
class MyInternalFrame extends JInternalFrame {
private AlphaComposite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
public MyInternalFrame(String title, int x, int y, int w, int h, final float alpha) {
super(title);
setClosable(true);
setBounds(x, y, w, h);
setVisible(true);
int sliderValue = (int) (alpha * 100);
comp = comp.derive(alpha);
final JSlider slider = new JSlider(0, 100, sliderValue);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setBorder(BorderFactory.createTitledBorder("Alpha Value"));
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent cEvt) {
float alpha = (float) slider.getValue() / 100f;
setAlpha(alpha);
MyInternalFrame.this.repaint();
Window win = SwingUtilities.getWindowAncestor(MyInternalFrame.this);
win.repaint();
}
});
add(new JLabel("My Label", SwingConstants.CENTER));
add(slider, BorderLayout.SOUTH);
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(comp);
super.paint(g);
}
public void setAlpha(float alpha) {
comp = comp.derive(alpha);
}
}
But note that this program is not fully fixed. You'll still see pixel errors if you drag one JInternalFrame over another. I still need to work the bugs out...