Alright the deal is I am trying to use the drawPie method to create my pie chart in an applet. After attempting google searches I find multiple tutorials that explain part of the process but not all of it. While trying to knit together partial information I am not getting the results I want.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JApplet;
import javax.swing.JComponent;
public class JLW_PieApplet extends JApplet {
class PieData extends JComponent {
PieValue[] slices = new PieValue[4];
PieData() {
slices[0] = new PieValue(35, Color.red);
slices[1] = new PieValue(33, Color.green);
slices[2] = new PieValue(20, Color.pink);
slices[3] = new PieValue(12, Color.blue);
}
public void paint(Graphics g) {
drawPie((Graphics2D)g, getBounds(), slices);
}
}
}
Ther isn't such method in Swing called drawPie. Without the contents of this method, we have no idea of how to help you
Try having a read through 2D Graphics and have a look at Ellipse2D in particular
The other problem I can see is you don't call super.paint(g) in your paint method. This is VERY, VERY, VERY important
You have a PieData component within your applet but you never add it, so you need to add it in init and bring in drawPie from your link above:
public class JLW_PieApplet extends JApplet {
public void init() {
add(new PieData());
}
class PieData extends JComponent {
PieValue[] slices = new PieValue[4];
PieData() {
slices[0] = ...
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawPie((Graphics2D) g, getBounds(), slices);
}
public void drawPie(Graphics2D g, Rectangle area, PieValue[] slices) {
...
Related
I have a draw class that extends JPanel and has a void method called drawing with repaint() in it.
public class draw extends JPanel {
public draw(int position_x, int position_y, int width, int height) {
positionx = position_x;
positiony = position_y;
this.width = width;
this.height = height;
}
public void drawing() {
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(positionx, positiony, width, height);
}
}
So, my intention is create a lot of this rectangles in a JPanel so they create a graphic bar.
public class coin_launcher {
public static void main(String[] args) {
JFrame frame = new JFrame("Coin Launcher");
frame.setVisible(true);
frame.setSize(1920, 1080);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
draw object = new draw(2,2,100,2);
frame.add(object);
object.drawing();
draw object2 = new draw(2,6,200,2);
frame.add(object2);
object2.drawing();
}
}
The problem is that when I call drawing() in both of the objects only one gets drawn.
If use the debugger its only the first one, if I dont, its only the second one. I need to make 100 bars but it literally repaints the JPanel every time, how can I add different draw class in one JPanel without erasing the others?
JFrame uses a BorderLayout by default, this means that only the last component added (to the default centre position) will be managed by the layout.
See BorderLayout for more details.
An immediate solution might be to use a different layout manager, but I would argue that's the wrong solution.
Instead, you should have ONE component, which is capable of paint multiple bars, based on the data available from a "model"
This decouples the source of the data from the presentation of the data, allowing to produce multiple different implementations of these, which shouldn't break the other.
In this case, the "view" shouldn't care how the data is obtained or marinated, only that it conforms to a specified contract, like wise the data doesn't care how its presented.
See Model-View-Controller for more details
This answer is a very basic and simplified example of
"you should have ONE component, which is capable of paint multiple
bars, based on the data available from a "model"
quoted from MadProgrammer's answer.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CoinLauncher {
public static void main(String[] args) {
JFrame frame = new JFrame("Coin Launcher");
frame.setSize(920, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//data to be painted. for better implementation use a model class that
//encapsulates the data
Rectangle[] bars = {
new Rectangle(2,2,100,2),
new Rectangle(2,6,200,2),
};
Draw object = new Draw(Arrays.asList(bars));
frame.add(object);
frame.setVisible(true);
}
}
class Draw extends JPanel {
private final List<Rectangle> bars;
Draw(List<Rectangle> bars) {
this.bars = bars;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
for(Rectangle bar : bars){
g.fillRect(bar.x, bar.y, bar.width, bar.height);
}
}
}
Implementing a model to encapsulate data need for the view, can be as simple as :
public class CoinLauncher {
public static void main(String[] args) {
JFrame frame = new JFrame("Coin Launcher");
frame.setSize(920, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Model model = new Model();
model.addBar( new Rectangle(2,2,100,2) );
model.addBar( new Rectangle(2,6,200,2) );
Draw object = new Draw(model);
frame.add(object);
frame.setVisible(true);
}
}
class Draw extends JPanel {
private final List<Rectangle> bars;
Draw(Model model) {
bars = model.getBars();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
for(Rectangle bar : bars){
g.fillRect(bar.x, bar.y, bar.width, bar.height);
}
}
}
class Model {
private final List<Rectangle> bars;
Model(){
bars = new ArrayList<>();
}
void addBar(Rectangle rectangle){
bars.add(rectangle);
}
List<Rectangle> getBars() { return bars; }
}
I tried few source codes of drawing in java and they were working fine, but when i tried to make one of my own I could not get the paint(Grahpics g) method to work! I looked again at the codes I have and checked some of the tutorials in Oracle's pages but i don't seem to be able to know why it would not work.
can someone please check it and tell me what is wrong here??
main method:
public class main
{
public static void main(String[] args)
{
new board();
}
}
board:
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class board implements ActionListener
{
private JFrame f = new JFrame("Speedy");
private JPanel gamePanel = new JPanel();
private Image bg = new ImageIcon(this.getClass().getResource("road.png")).getImage();
private Timer t;
private car myCar = new car();
public board()
{
t = new Timer(50,this);
t.start();
gamePanel.setSize(600,400);
gamePanel.setDoubleBuffered(true);
gamePanel.setFocusable(true);
gamePanel.addKeyListener(new TAdapter());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(gamePanel,BorderLayout.CENTER);
//f.addKeyListener(new TAdapter());
f.setBounds(200,100,600,400);
f.setVisible(true);
f.revalidate();
f.repaint();
}
public void paint(Graphics g) {
gamePanel.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(bg,0,0,null);
g2d.drawImage(myCar.getImg(), myCar.xPos, myCar.yPos, null);
System.out.println("Painted");
g.dispose();
}
public void actionPerformed(ActionEvent e)
{
gamePanel.repaint();
//System.out.println("Painting..");
}
private class TAdapter extends KeyAdapter {
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e)
{
myCar.keyPressed(e);
System.out.println("You pressed: "+e);
}
}
}
car.java:
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon
;
public class car
{
private Image image;
public int xPos,yPos;
public car()
{
image = new ImageIcon(this.getClass().getResource("car.png")).getImage();
xPos = 300;
yPos = 200;
System.out.println(image.getWidth(null));
}
public Image getImg() {return image;}
public void move() {}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) xPos -= 1;
if (key == KeyEvent.VK_RIGHT)xPos += 1;
if (key == KeyEvent.VK_UP) yPos -= 1;
if (key == KeyEvent.VK_DOWN) yPos += 1;
}
}
There are no errors, it shows me the width of the image which is right, also the timer triggers the ActionListener, also KeyListener is working, but the images would not draw! the paint(Graphics g) method just does not want to get triggered!
Googling it did not help.. I thought this would be a common problem but nobody has the problem I have, all solutions failed me.
help please?
If someone can explain it would be most appreciated!
Your class Board does not extend the JPanel class. So the paint() method is never called by the Swing.
Also, the statement gamePanel.repaint() will only execute the default JPanel paint() method of gamePanel. Instead you want the overridden paint method to be executed, so might want to do this:
public class Board extends JPanel implements ActionListener {
....
public void paint(Graphics g) {
this.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(bg,0,0,null);
g2d.drawImage(myCar.getImg(), myCar.xPos, myCar.yPos, null);
System.out.println("Painted");
g2d.dispose();
}
....
}
Replace your action functionality with this:
public void actionPerformed(ActionEvent e) {
this.repaint();
}
Alternative solution:
If you do not want your Board class to extend JPanel, you can also override the paint() method of the gamePanel as you initialize it.
gamePanel = new JPanel() {
#Override
public void paint(Graphics g) {
this.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(bg,0,0,null);
g2d.drawImage(myCar.getImg(), myCar.xPos, myCar.yPos, null);
g2d.dispose();
}
};
However, I would recommend the first solution rather than this one with anonymous classes.
When you call repaint on some container, then what happens is that Swing looks at all the components in that container and calls their paint method.
However, your board class (you should be calling it Board, by the way. Class names should always start with a capital) is not a component of your JFrame. When you call repaint, Swing will attempt to call the paint method of the JPanel that is a component of that JFrame. But you didn't override that method. You just added a paint method to your board, and board is not a component of the JFrame.
For this reason, usually you are supposed to create a class that extnds JPanel or some other component, and then add the current object of that class as a component to the JFrame. This way, your paint method will be called when the JFrame is repainted.
Your "main" class (board) should extend JPanel to work as expected.
With your way, paint would never be called. it acts like any normal self-written function.
If you want to keep things as they are, you can do something ike that:
gamePanel = new JPanel()
{
#Override
public void paint(Graphics g)
{
//your code here
}
};
Please keep in mind that a Class name should start with a capital letter. It won't make any errors but it is a naming convention as you can see here:
http://www.oracle.com/technetwork/java/codeconventions-135099.html
I need help with this code. My g.drawLine(0,0,300,300) is not working. It was working until monday, I don't know what is going wrong. I use the g.drawLine(0,0,300,300) in order to test before using the plota_pixel() method. g.drawLine(0,0,300,300) shoud print a line from (0,0) to (300,300) on the Jpanel panel
MainView Class:
package alexandre.VIEW;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainView {
private JFrame janela;
public JPanel panel;
public MainView()
{
janela = new JFrame("Exercicio 15/09");
janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
this.ShowView();
}
public void ShowView()
{
janela.pack();
janela.setSize(750,600);
janela.setLayout(null);
janela.add(panel);
panel.setBounds(0,0,710,600);
janela.setVisible(true);
System.out.println("OIdsazxc");
Graphics g = panel.getGraphics();
g.setColor(Color.BLACK);
g.drawLine(0,0,300,300);
}
public void plota_pixel(int x, int y)
{
Graphics g = panel.getGraphics();
g.drawLine(x, y, x, y);
}
}
Starter Class:
package alexandre.CONTROL;
import alexandre.VIEW.MainView;
public class Starter {
public static void main(String[] args) {
MainView view = new MainView();
view.ShowView();
}
}
Using and drawing with the Graphics object from panel.getGraphics() does not work (see below links for the "why"). You will have to override the method "paintComponent" for the the JPanel, where the input parameter is the Graphics object
(Also quick note - standard method naming has the first letter lowercase so ShowView() should be showView())
public MainView()
{
janela = new JFrame("Exercicio 15/09");
janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine(0,0,300,300);
}
};
this.showView();
}
public void showView() {
janela.pack();
janela.setSize(750, 600);
janela.setLayout(null);
janela.add(panel);
panel.setBounds(0, 0, 710, 600);
panel.setVisible(true);
janela.repaint();
}
Check out the following stack overflow question
Drawing an object using getGraphics() without extending JFrame
And this resource (it's also in the linked question)
http://docs.oracle.com/javase/tutorial/uiswing/painting/
You should set the panel visible as the last thing in the ShowViewmethod.
public void ShowView()
{
//your code
janela.setVisible(true);
}
I am trying to draw to a single panel from multiple sources in java. However when I try this test code I get applet not initialized. Keeping in mind I am fairly new to this. How would I get rid of this error and or draw to a panel from multiple sources.
import java.awt.Graphics;
import javax.swing.JPanel;
class Surface extends JPanel {
public void init() {
}
public void paintComponent(Graphics g){
super.paintComponent(g);
DrawRect d = new DrawRect(this);
d.draw( g );
}
}
class DrawRect {
Surface surface;
Graphics g;
public DrawRect(Surface surface)
{
g = surface.getGraphics();
}
public void draw( Graphics g )
{
g.fillRect(20,20,100,50); // (now this will work).
}
}
I am working on a project to make a JApplet's contents automatically scale to the size specified in the html. I realize this is the kind of thing that layout managers were made for, however as I am not permitted to rewrite the entire applets structure, i decided i would try to override paint and simply set the AffineTransform of the Graphics object to an appropriately scaled version, then capture mouse Events in the top container and scale them back with an appropriate scaling transform. Im getting stuck on the drawing part at the moment. When viewed in a web browser, it renders the scaled version correctly once, then the image is shrunk back to its original size. In addition, it seems that the paint method in JApplet is only ever called once. Here is a cropped version of my code which focuses on the problem. Any help would be appreciated. Thanks in advance.
import javax.swing.JApplet;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
public class Test extends JApplet
{
public static final int ORIGINAL_APPLET_WIDTH = 1024;
public static final int ORIGINAL_APPLET_HEIGHT = 800;
private AffineTransform scalingTransform;
private AffineTransform inverseScalingTransform;
#Override
public void init()
{
double xFactor = ((double)(this.getWidth()))/((double)(Test.ORIGINAL_APPLET_WIDTH));
double yFactor = ((double)(this.getHeight()))/((double)(Test.ORIGINAL_APPLET_HEIGHT));
this.scalingTransform = new AffineTransform();
this.inverseScalingTransform = new AffineTransform();
this.scalingTransform.scale(xFactor,yFactor);
this.inverseScalingTransform.scale(1D/xFactor,1D/yFactor);
}
#Override
public void paint(Graphics g)
{
((Graphics2D)g).setTransform(Test.this.scalingTransform);
super.paint(g);
}
}
I figured out, after much research, that the problem was that JApplet's paint method doesn't get called very often. The instead the content pane has its own drawing surface, so i simply had to replace the content pane to get it to upload. heres the way i did it:
#Override
public void init()
{
double xFactor = ((double)(this.getWidth()))/((double)(qt.ORIGINAL_APPLET_WIDTH));
double yFactor = ((double)(this.getHeight()))/((double)(qt.ORIGINAL_APPLET_HEIGHT));
this.scalingTransform = new AffineTransform();
this.inverseScalingTransform = new AffineTransform();
this.scalingTransform.scale(xFactor,yFactor);
this.inverseScalingTransform.scale(1D/xFactor,1D/yFactor);
JPanel drawScale = new JPanel()
{
#Override
public void paint(Graphics g)
{
((Graphics2D)g).setTransform(Test.this.scalingTransform);
super.paint(g);
}
#Override
public void paintAll(Graphics g)
{
((Graphics2D)g).setTransform(Test.this.scalingTransform);
super.paintAll(g);
}
#Override
public void paintComponents(Graphics g)
{
((Graphics2D)g).setTransform(Test.this.scalingTransform);
super.paintComponents(g);
}
#Override
public void paintComponent(Graphics g)
{
((Graphics2D)g).setTransform(Test.this.scalingTransform);
super.paintComponents(g);
}
};
Container oldPane = this.getContentPane();
drawScale.setLayout(oldPane.getLayout());
this.setContentPane(drawScale);
}
these paint methods were of course in addition to the ones in the applet.