In my code after i added code to paintComponent() when i run it, all the JLabel, textfields, and buttons disappear the textfields and buttons reappear when i click on them while the program is running but i still can't see any of the JLabels.
I hope it is something silly i have commented out the code in the paintComponent() method that seems to cause this error.
public class snowBoarding extends JFrame {
private JButton getReset() {
if (Reset == null) {
Reset = new JButton();
Reset.setBounds(new Rectangle(162, 411, 131, 39));
Reset.setFont(new Font("Dialog", Font.BOLD, 18));
Reset.setText("Reset");
Reset.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e){
textField_1.setText("0");
textField_2.setText("0");
textField_3.setText("0");
textField_4.setText("0");
textField_5.setText("0");
textField_6.setText("0");
textField_7.setText("0");
textField_8.setText("0");
textField_9.setText("0");
textField_10.setText("0");
textField_11.setText("0");
textField.setText("0");
total_1.setText("0");
total_2.setText("0");
Overall.setText("0");
DrawPanel.clear(DrawPanel.getGraphics());
DrawPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
}
});
}
return Reset;
}
public JButton getButton_calc_draw() {
if (Button_calc_draw == null) {
Button_calc_draw = new JButton();
Button_calc_draw.setBounds(303, 411, 131, 39);
Button_calc_draw.setFont(new Font ("Dialog", Font.BOLD, 18));
Button_calc_draw.setText("Draw");
Button_calc_draw.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
// Get values from the text fields
run_1[0] = Integer.parseInt(textField.getText());
run_1[1] = Integer.parseInt(textField_1.getText());
run_1[2] = Integer.parseInt(textField_2.getText());
run_1[3] = Integer.parseInt(textField_3.getText());
run_1[4] = Integer.parseInt(textField_4.getText());
run_1[5] = Integer.parseInt(textField_5.getText());
for (int i = 0; i < run_1.length; i++) {
temp[i] = run_1[i];
}
Arrays.sort(temp);
for (int i = 1; i < (temp.length -1) ; i++){
avg1+=temp[i];
}
avg1 = avg1/4;
run_2[0] = Integer.parseInt(textField_6.getText());
run_2[1] = Integer.parseInt(textField_7.getText());
run_2[2] = Integer.parseInt(textField_8.getText());
run_2[3] = Integer.parseInt(textField_9.getText());
run_2[4] = Integer.parseInt(textField_10.getText());
run_2[5] = Integer.parseInt(textField_11.getText());
for (int i = 0; i < run_2.length; i++) {
temp[i] = run_2[i];
}
Arrays.sort(temp);
for (int i = 1; i < (temp.length -1) ; i++){
avg2+=temp[i];
}
avg2 = avg2/4;
if (avg1 > avg2){
OverallScore = avg1;
}
else {
OverallScore = avg2;
}
total_1.setText(Integer.toString(avg1));
total_2.setText(Integer.toString(avg2));
Overall.setText(Integer.toString(OverallScore));
DrawPanel.repaint();
}
// Transfer the image from the BufferedImage to the JPanel to make it visible.
;
});
}
return Button_calc_draw;
}
}
});
}
return Reset;
}
private myJPanel getDrawPanel() {
if (DrawPanel == null) {
DrawPanel = new myJPanel();
DrawPanel.setLayout(new GridBagLayout());
DrawPanel.setBounds(new Rectangle(258, 39, 326, 361));
DrawPanel.setBackground(Color.white);
DrawPanel.setEnabled(true);
DrawPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
//Instantiate the BufferedImage object and give it the same width
// and height as that of the drawing area JPanel
img = new BufferedImage(DrawPanel.getWidth(),
DrawPanel.getHeight(),
BufferedImage.TYPE_INT_RGB);
//Get its graphics context. A graphics context of a particular object allows us to draw on it.
g2dImg = (Graphics2D)img.getGraphics();
//Draw a filled white coloured rectangle on the entire area to clear it.
g2dImg.setPaint(Color.WHITE);
g2dImg.fill(new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));
}
return DrawPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
snowBoarding thisClass = new snowBoarding();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}
public snowBoarding() {
super();
setResizable(false);
getContentPane().setLayout(null);
initialize();
}
private void initialize() {
this.setSize(600, 500);
this.setContentPane(getJContentPane());
this.setTitle("Snowboarding Score Calculator");
this.setResizable(false);
this.setVisible(true);
}
}
class myJPanel extends JPanel {
BufferedImage img;
Graphics2D g2dImg;
private static final long serialVersionUID = 1L;
private Rectangle2D.Double rectangle;
public void paintComponent(Graphics g) {
//Must be called to draw the JPanel control.
// As a side effect, it also clears it.
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
rectangle = new Rectangle2D.Double(0, 260-score[0] * 2, 25, score[0] * 2);
g2D.setPaint(Color.blue);
g2D.fill(rectangle);
g2D.draw(rectangle);
}
protected void clear(Graphics g) {
super.paintComponent(g);
// Also clear the BufferedImage object by drawing a white coloured filled rectangle all over.
g2dImg.setPaint(Color.WHITE);
g2dImg.fill(new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));
}
}
edit: removing unnecessary code
i need the repaint to draw rectangles using the run_1 and the run_2 array as the x or y values after i click draw and the reset to return the painted image back to a white slate.
draw button --> draws the graph
reset button --> removes the graph so that a new graph can be created.
You shall not use g2dImg in paintComponent(), but g instead (the parameter received by method paintComponent()). More precisely, ((Grpahics2D)g) instead of g2dImg.
g2dImg doesn't seem to be initialized in your code posted here, maybe you have done it somewhere...
More generally, you shall always use the Graphics instance you received in paint methods (casting it to Graphics2D if needed). You shall not try to reuse/share/store instances of Graphics.
The same applies for the clear() method.
Here is an example of how to rewrite this paintComponent() method:
private boolean shallPaint = false;
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (shallPaint) {
Graphics2D g2D = (Graphics2D) g;
rectangle = new Rectangle2D.Double(0, 260-score1 * 2, 25, score1 * 2);
g2D.setPaint(Color.blue);
g2D.fill(rectangle);
g2D.draw(rectangle);
}
}
public void setShallPaint(boolean pShallPaint) {
shallPaint = pShallPaint;
}
Then simply call myJPanel.repaint() to repaint it.
You shall replace, in your reset button:
DrawPanel.clear(DrawPanel.getGraphics());
with:
DrawPanel.setShallPaint(false);
DrawPanel.repaint();
And in Button_calc_draw:
DrawPanel.setShallPaint(true);
DrawPanel.repaint();
Related
I have a simple game of pong where when the user clicks a JButton which is displayed on the JPanel it should reset the game. How can I do this? I was thinking just remove the JPanel and add a new one (the JPanel contains all of the necessary code/class references for the game) I tried writing this however, and it didn't work, nothing happens. Here is my code:
JFrame Class:
public class Window extends JFrame implements ActionListener {
static int length = 1000;
static int height = 1000;
Display display = new Display();
Window() {
setTitle("Program Display");
setSize(length + 22, height + 40);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton restart = new JButton("Start New Game");
add(display);
display.add(restart);
restart.addActionListener(this);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
remove(display);
Display display2 = new Display();
JButton restart = new JButton("Start New Game");
add(display2);
display2.add(restart);
restart.addActionListener(this);
revalidate();
repaint();
}
}
JPanel Class:
public class Display extends JPanel implements ActionListener {
int up = 0;
int down = 500;
double ballx = 500;
double bally = 500;
char ballDirection;
Rectangle border;
static Rectangle borderEast;
static Rectangle borderNorth;
static Rectangle borderSouth;
static Rectangle borderWest;
static boolean gameOver;
Timer timer;
Paddle p;
Ball b;
Display() {
p = new Paddle();
b = new Ball();
up = p.up;
down = p.down;
ballx = b.ballx;
bally = b.bally;
ballDirection = b.ballDirection;
initTimer();
b.startBall();
addKeyListener(p);
setFocusable(true);
}
public void initTimer() {
timer = new Timer(10, this);
timer.start();
}
public void setUpBorders(Graphics2D g2d) {
border = new Rectangle(0, 0, Window.length, Window.height);
borderEast = new Rectangle(Window.length, 0, 2, Window.height);
borderWest = new Rectangle(0, 0, 2, Window.height);
borderSouth = new Rectangle(0, Window.height, Window.length, 2);
borderNorth = new Rectangle(0, 0, Window.length, 2);
g2d.setColor(Color.RED);
g2d.draw(border);
}
public void paintPaddle(Graphics2D g2d) {
g2d.setColor(new Color(0, 130, 130));
g2d.fill(p.paddle);
}
public void paintBall(Graphics2D g2d) {
g2d.setColor(new Color(0, 130, 130));
g2d.fillOval((int) ballx, (int) bally, 20, 20);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.BLACK);
Graphics2D g2d = (Graphics2D) g;
setUpBorders(g2d);
paintPaddle(g2d);
paintBall(g2d);
if(gameOver == true) {
Font custom = new Font("Dialog", Font.BOLD, 60);
g2d.setColor(Color.RED);
g2d.setFont(custom);
g2d.drawString("Game Over. Your score was: " + Ball.score + "!", 50, 500);
}
}
public void checkBorderHit() {
b.checkBorderHit();
p.checkBorderHit();
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
up = p.up;
down = p.down;
ballx = b.ballx;
bally = b.bally;
ballDirection = b.ballDirection;
b.moveBall();
checkBorderHit();
repaint();
}
}
You didn't say what exactly doesn't work, but you forgot to call revalidate() and repaint() after adding display2. If your problem was that after pressing the button nothing happens, this will probably solve it.
Edit:
We still can't run you code, because the Ball and Paddle class are missing (my mistake for not mentioning that), but try to set important variables like gameOver false when first "mentioning them" (I don't know the proper term, just do static boolean gameOver = false; instead of static boolean gameOver;). Do this in all other classes also. Sorry for not saying which variables you exactly must change, but I'm not saying anything I'm not 100% sure about without being able to test it :P (maybe a more experienced person can help you more)
I have to programm a Shikaku-Game and I have no the problem that I can not use one of the setLine-Methods from the ViewIcon-Class in the mouseReleased-Method of the class MyMouseAdapter.
Do you know a way how to use one of the methods?
Thanks and Cheers,
Me
Class MouseMain and Class MyMouseAdapter:
class MouseMain extends JFrame{
Container cont;
public MouseMain () {
super("Test");
cont = getContentPane();
p1 = new defaultPaterns(2);
p1.setLayout(new GridLayout(2, 2, 1, 1));
for (int i = 0; i < gameSize; i++) {
for (int j = 0; j < gameSize; j++) {
JLabel label = new JLabel(new ViewIcon());
label.setName (j + ";" + i);
label.addMouseListener(new MyMouseAdapter());
p1.add(label);
myLabels[j][i] = label;
}
}
cont.add(p1, BorderLayout.CENTER );
JPanel p2 = new JPanel();
cont.add(p2, BorderLayout.SOUTH);
setVisible(true);
}
public class MyMouseAdapter extends MouseAdapter {
public void mouseEntered(MouseEvent e) {
lastEntered = e.getComponent();
}
public void mousePressed(MouseEvent e) {
mousePressed = e.getComponent();
coordPressed = new Coordinate(mousePressed.getName());
System.out.println("mousePressed " + mousePressed.getName());
}
public void mouseReleased(MouseEvent e) {
mouseReleased = lastEntered;
coordReleased = new Coordinate(mouseReleased.getName());
System.out.println("mouseReleased " + mouseReleased.getName());
if (mouseReleased.getName().equals("0;0")) {
mouseReleased.setForeground(Color.RED);
mouseReleased.repaint();
}
}
}
Class ViewIcon:
class ViewIcon extends JLabel implements Icon {
Graphics2D g2;
int width;
int height;
public void paintIcon(Component c, Graphics g, int x, int y) {
g2 = (Graphics2D) g;
width = c.getWidth();
height = c.getHeight();
g2.setColor(Color.LIGHT_GRAY);
g2.fillRect(0, 0, width, height);
}
public void setLeftLine() {
g2.setStroke (new BasicStroke (10));
g2.setColor(Color.RED);
g2.drawLine(0, 0, 0, height);
}
}
class ViewIcon extends JLabel implements Icon {
Don't extend JLabel. All your code is doing is implementing the Icon interface.
I can not use one of the setLine-Methods from the ViewIcon-Class
Custom painting should only be done in the paintIcon(...) method. You should NEVER invoke a painting method directly.
If you want to change the appearance of your painting then you need to set properties of the Icon. For example to paint the top line you rename and change your setTopLine(...) method to look something like:
public void setTopLinePainted(boolean topLinePainted)
{
this.topLinePainted = topLinePainted;
}
Then in the paintIcon(...) method you have code like:
g2.fillRect(0, 0, width, height);
if (topLinePainted)
{
g2.setStroke (new BasicStroke (10));
g2.setColor(Color.RED);
g2.drawLine(0, 0, width, 0);
}
Then in your mouseReleased(...) code you do something like:
JLabel label = (JLabel)lastEntered;
ViewIcon icon = (ViewIcon)label.getIcon();
icon.setTopLinePainted( true );
label.repaint();
Since Java only supports single inheritance, I desire to paint directly on an instance of a JPanel that is a member of the class Panel. I grab an instance of Graphics from the member and then paint whatever I desire onto it.
How can I not inherit from JComponent or JPanel and still utilize getGraphics() for painting on this without overriding public void paintComponent(Graphics g)?
private class Panel {
private JPanel panel;
private Graphics g;
public Panel() {
panel = new JPanel();
}
public void draw() {
g = panel.getGraphics();
g.setColor(Color.CYAN);
g.draw(Some Component);
panel.repaint();
}
}
The panel is added to a JFrame that is made visible prior to calling panel.draw(). This approach is not working for me and, although I already know how to paint custom components by inheriting from JPanel and overriding public void paintComponent(Graphics g), I did not want to inherit from JPanel.
Here are some very simple examples which show how to paint outside paintComponent.
The drawing actually happens on a java.awt.image.BufferedImage, and we can do that anywhere, as long as we're on the Event Dispatch Thread. (For discussion of multithreading with Swing, see here and here.)
Then, I'm overriding paintComponent, but only to paint the image on to the panel. (I also paint a little swatch in the corner.)
This way the drawing is actually permanent, and Swing is able to repaint the panel if it needs to without causing a problem for us. We could also do something like save the image to a file easily, if we wanted to.
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
/**
* Holding left-click draws, and
* right-clicking cycles the color.
*/
class PaintAnyTime {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new PaintAnyTime();
}
});
}
Color[] colors = {Color.red, Color.blue, Color.black};
int currentColor = 0;
BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
Graphics2D imgG2 = img.createGraphics();
JFrame frame = new JFrame("Paint Any Time");
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Creating a copy of the Graphics
// so any reconfiguration we do on
// it doesn't interfere with what
// Swing is doing.
Graphics2D g2 = (Graphics2D) g.create();
// Drawing the image.
int w = img.getWidth();
int h = img.getHeight();
g2.drawImage(img, 0, 0, w, h, null);
// Drawing a swatch.
Color color = colors[currentColor];
g2.setColor(color);
g2.fillRect(0, 0, 16, 16);
g2.setColor(Color.black);
g2.drawRect(-1, -1, 17, 17);
// At the end, we dispose the
// Graphics copy we've created
g2.dispose();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(img.getWidth(), img.getHeight());
}
};
MouseAdapter drawer = new MouseAdapter() {
boolean rButtonDown;
Point prev;
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
prev = e.getPoint();
}
if (SwingUtilities.isRightMouseButton(e) && !rButtonDown) {
// (This just behaves a little better
// than using the mouseClicked event.)
rButtonDown = true;
currentColor = (currentColor + 1) % colors.length;
panel.repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (prev != null) {
Point next = e.getPoint();
Color color = colors[currentColor];
// We can safely paint to the
// image any time we want to.
imgG2.setColor(color);
imgG2.drawLine(prev.x, prev.y, next.x, next.y);
// We just need to repaint the
// panel to make sure the
// changes are visible
// immediately.
panel.repaint();
prev = next;
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
prev = null;
}
if (SwingUtilities.isRightMouseButton(e)) {
rButtonDown = false;
}
}
};
PaintAnyTime() {
// RenderingHints let you specify
// options such as antialiasing.
imgG2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
imgG2.setStroke(new BasicStroke(3));
//
panel.setBackground(Color.white);
panel.addMouseListener(drawer);
panel.addMouseMotionListener(drawer);
Cursor cursor =
Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
panel.setCursor(cursor);
frame.setContentPane(panel);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
It's also possible to set up a JLabel with an ImageIcon, although personally I don't like this method. I don't think JLabel and ImageIcon are required by their specifications to see changes we make to the image after we've passed it to the constructors.
This way also doesn't let us do stuff like painting the swatch. (For a slightly more complicated paint program, on the level of e.g. MSPaint, we'd want to have a way to select an area and draw a bounding box around it. That's another place we'd want to be able to paint directly on the panel, in addition to drawing to the image.)
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
/**
* Holding left-click draws, and
* right-clicking cycles the color.
*/
class PaintAnyTime {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new PaintAnyTime();
}
});
}
Color[] colors = {Color.red, Color.blue, Color.black};
int currentColor = 0;
BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
Graphics2D imgG2 = img.createGraphics();
JFrame frame = new JFrame("Paint Any Time");
JLabel label = new JLabel(new ImageIcon(img));
MouseAdapter drawer = new MouseAdapter() {
boolean rButtonDown;
Point prev;
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
prev = e.getPoint();
}
if (SwingUtilities.isRightMouseButton(e) && !rButtonDown) {
// (This just behaves a little better
// than using the mouseClicked event.)
rButtonDown = true;
currentColor = (currentColor + 1) % colors.length;
label.repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (prev != null) {
Point next = e.getPoint();
Color color = colors[currentColor];
// We can safely paint to the
// image any time we want to.
imgG2.setColor(color);
imgG2.drawLine(prev.x, prev.y, next.x, next.y);
// We just need to repaint the
// label to make sure the
// changes are visible
// immediately.
label.repaint();
prev = next;
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
prev = null;
}
if (SwingUtilities.isRightMouseButton(e)) {
rButtonDown = false;
}
}
};
PaintAnyTime() {
// RenderingHints let you specify
// options such as antialiasing.
imgG2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
imgG2.setStroke(new BasicStroke(3));
//
label.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
label.setBackground(Color.white);
label.setOpaque(true);
label.addMouseListener(drawer);
label.addMouseMotionListener(drawer);
Cursor cursor =
Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
label.setCursor(cursor);
frame.add(label, BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class SomeComponent extends JComponent {
private Graphics2D g2d;
public void paintComponent(Graphics g) {
g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
g2d.scale(scale, scale);
g2d.drawOval(0, 0, importance, importance);
}
public Graphics2D getG2d() {
return g2d;
}
public void setG2d(Graphics2D g2d) {
this.g2d = g2d;
}
}
then you can do the following
get the SomeComponent instance in the panel and modify it
Graphics2D x= v.getPanel().get(i).getG2d;
x.setColor(Color.BLUE);
v.getPanel().get(i).setG2d(x);
v.getPanel().repaint();
v.getPanel().revalidate();
V is a class that extends JFrame and contains the panel in it AND
i is instance of SomeComponent
I have a JLayeredPane with 4 layers added to it. 1 base layer, which is opaque and three 'transparent' layers (setOpaque(false)).
The problem is that although the panels are drawn onto, with every refresh a gray color is shown. The same thing happens if there is no refresh happening. In other words, instead of showing whatever was drawn onto the base layer, a gray color is shown, I assume this is from one of the layers above.
Here is a SSCCE - I'm not sure if this is short enough but it shows my problem.
public class SSCCE extends JLayeredPane{
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(950, 600);
frame.add(new SSCCE());
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// private fields
private boolean drawInitial = true;
private boolean drawn = false;
private JPanel overlay, base, iconPanel, middle;
private BufferedImage baseBuffer, midBuffer, overlayBuffer, iconBuffer;
private boolean updateInit = true;
private Rectangle2D stored = new Rectangle2D.Double(60, 60, 40, 100);
public SSCCE() {
setBorder(new LineBorder(Color.BLACK));
setDoubleBuffered(false);
setOpaque(true);
setSize(new Dimension(950, 600));
setPreferredSize(new Dimension(950, 600));
base = new JPanel();
base.setBackground(new Color(0,0,0,0));
base.setSize(new Dimension(getWidth(), getHeight()));
this.add(base, new Integer(0));
middle = new JPanel();
middle.setSize(new Dimension(getWidth(), getHeight()));
middle.setBackground(new Color(0,0,0,0));
middle.setOpaque(false);
this.add(middle, new Integer(1));
overlay = new JPanel();
overlay.setBackground(new Color(0,0,0,0));
overlay.setOpaque(false);
overlay.setSize(new Dimension(getWidth(), getHeight()));
this.add(overlay, new Integer(2));
iconPanel = new JPanel();
iconPanel.setBackground(new Color(0,0,0,0));
iconPanel.setSize(getWidth(), getHeight());
iconPanel.setOpaque(false);
this.add(iconPanel, new Integer(3));
}
public void update() {
if(updateInit){
checkBuffer();
updateInit = false;
}
drawInfoRect();
drawIcon();
highlightPath(stored);
}
public void render() {
if (drawInitial) {
Graphics2D baseGraphics = (Graphics2D) base.getGraphics();
baseGraphics.drawImage(baseBuffer, 0, 0, null);
}
setResistanceColor((Graphics2D)baseBuffer.getGraphics());
middle.getGraphics().drawImage(midBuffer, 0, 0, null);
iconPanel.getGraphics().drawImage(iconBuffer, 0, 0, null);
drawInfoRect();
base.getGraphics().drawImage(baseBuffer, 0, 0, null);
if (drawn) {
overlay.getGraphics().drawImage(overlayBuffer, 0, 0, null);
}
repaint();
}
// /**
// * draws the appropriate colour
// */
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
update();
render();
}
/**
* sets the appropriate colours according to the resistance
* #param g2
*/
private void setResistanceColor(Graphics2D g2) {
Rectangle2D sp = new Rectangle2D.Double(50,50, 50, 50);
g2.setColor(Color.GREEN);
g2.fill(sp);
g2.setColor(Color.BLACK);
}
/**
* checks if there already exists an image to buffer with
*/
private void checkBuffer() {
if (baseBuffer == null) {
baseBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));
// background color
Graphics2D g2 = (Graphics2D) baseBuffer.getGraphics();
g2.setColor(Color.decode("#729fcf"));
Rectangle2D rect = new Rectangle2D.Double(0, 0, baseBuffer.getWidth(), baseBuffer.getHeight());
g2.fill(rect);
}
if (midBuffer == null) {
midBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));
// background color
Graphics2D g2 = (Graphics2D) midBuffer.getGraphics();
g2.setColor(Color.RED);
Rectangle2D rect = new Rectangle2D.Double(0, 0, midBuffer.getWidth(), midBuffer.getHeight());
g2.fill(rect);
}
if (overlayBuffer == null) {
overlayBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));
}
if (iconBuffer == null) {
iconBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));
}
}
public void highlightPath(Shape enlighten) {
Area area = new Area();
area.add(new Area(enlighten));
// clearing image before drawing
Graphics2D midBufferG = (Graphics2D) midBuffer.getGraphics();
clearImage(midBufferG);
midBufferG.setColor(Color.white);
// adds a transparent overlay
midBufferG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.50f));
midBufferG.fill(area);
}
public void drawIcon() {
Graphics2D iconG = (Graphics2D) iconBuffer.getGraphics();
clearImage(iconG);
}
public void drawInfoRect() {
Graphics2D graph = (Graphics2D) overlayBuffer.getGraphics();
Rectangle2D visible = getVisibleRect();
int boxX = (int) (visible.getX() + 50);
int boxY = (int) (visible.getY() + 450);
RoundRectangle2D rect = new RoundRectangle2D.Double(boxX, boxY, 200, 150, 25, 25);
graph.setColor(Color.decode("#729fcf").darker());
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
graph.fill(rect);
graph.setColor(Color.BLACK);
drawn = true;
}
private void clearImage(Graphics2D graph){
graph.setComposite(AlphaComposite.Clear);
graph.fillRect(0, 0, overlayBuffer.getWidth(), overlayBuffer.getHeight());
graph.setComposite(AlphaComposite.SrcOver);
}
}
It might be some basic mistake I made. Thanks for your help!
One of the previously suggested answers actually solved my question, but for some reason they deleted their answer.
Setting the Background of my panels to setBackground(new
Color(0,0,0,0)); solved my problems.
According to the person that suggested this, the cause of that is the fact that JComponent may or may not draw transparent if not explicitly specified.
Thanks again!
I want to change Background color of Jpanel and its font on button click.
Can anyone tell me what i am doing wrong?
Can I set JPanel background transparent?if yes How?
On button click test4.action method is called where i need to change Jpanel background color?
Here is the code:
import java.applet.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.*;
public class test3 extends Applet {
JPanel c;
JScrollPane s;
Button connect;
Panel controls;
Color back, fore;
public void init() {
back = Color.black;
fore = Color.white;
setBackground(Color.darkGray);
setLayout(new BorderLayout());
s = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//s.setSize(100, 100);
add("Center", s);
c = new myCanvas11(this);
s.setOpaque(false);
s.setViewportView(c);
//s.add(c);
c.setSize(1000, 16000);
add("North", controls = new Panel());
controls.setLayout(new FlowLayout());
controls.add(connect = new Button("Change Color"));
}
public void start() {
// s.setScrollPosition(100, 100);
}
public boolean action(Event e, Object arg) {
back = Color.magenta;
fore = Color.blue;
//setBackground(back);
//invalidate();
//repaint();
c.setBackground(back);
c.repaint();
//s.getViewport().setBackground(back);
// s.getViewport().repaint();
//c.repaint();
c.setFocusable(true);
return true;
}
}
class myCanvas11 extends JPanel implements KeyListener {
Image buffImage;
Graphics offscreen;
boolean initDone = false;
int chw, chh; // size of a char (in pixels)
int chd; // offset of char from baseline
int width, height; // size of applet (in pixels)
int w, h; // size of applet (in chars)
Font fn;
Graphics gr;
int nh, nw;
test3 owner;
static int counter = 0;
myCanvas11(test3 t) {
super();
owner = t;
nh = 16000;
nw = 1000;
this.setOpaque(true);
this.setFocusable(true);
addKeyListener(this);
}
public void reshape(int nx, int ny, int nw1, int nh1) {
if (nw1 != width || nh1 != height) {
width = nw;
height = nh;
gr = getGraphics();
fn = new Font("Courier", Font.PLAIN, 11);
if (fn != null) {
gr.setFont(fn);
}
FontMetrics fnm = gr.getFontMetrics();
chw = fnm.getMaxAdvance();
chh = fnm.getHeight();
chd = fnm.getDescent();
// kludge for Windows NT and others which have too big widths
if (chw + 1 >= chh) {
chw = (chw + 1) / 2;
}
// work out size of drawing area
h = nh / chh;
w = nw / chw;
buffImage = this.createImage(nw, nh);
offscreen = buffImage.getGraphics();
//offscreen.setColor(Color.black);
//offscreen.fillRect(0, 0, nw, nh);
offscreen.setColor(Color.blue);
offscreen.setFont(fn);
if (initDone) {
offscreen.drawString("Hello World!", 0, 50);
} else {
offscreen.drawString("khushbu", 2, 50);
}
initDone = true;
offscreen.drawImage(buffImage, 0, 0, this);
}
super.reshape(nx, ny, nw, nh);
}
public void paint(Graphics g) {
// if (!initDone)
// initpaint(g);
// else
g.drawImage(buffImage, 0, 0, this);
//g.drawImage(buffImage, 0, 0, owner.back, this);
}
public void update(Graphics g) {
g.drawImage(buffImage, 0, 0, this);
super.update(g);
//g.drawImage(buffImage, 0, 0, owner.back, this);
}
public void initpaint(Graphics g) {
try {
nh = getHeight();
nw = getWidth();
gr = getGraphics();
fn = new Font("Courier", Font.PLAIN, 11);
if (fn != null) {
gr.setFont(fn);
}
FontMetrics fnm = gr.getFontMetrics();
chw = fnm.getMaxAdvance();
chh = fnm.getHeight();
chd = fnm.getDescent();
// kludge for Windows NT and others which have too big widths
if (chw + 1 >= chh) {
chw = (chw + 1) / 2;
}
// work out size of drawing area
h = nh / chh;
w = nw / chw;
buffImage = this.createImage(nw, nh);
offscreen = buffImage.getGraphics();
//offscreen.setColor(Color.black);
//offscreen.fillRect(0, 0, nw, nh);
offscreen.setColor(Color.white);
offscreen.setFont(fn);
if (initDone) {
offscreen.drawString("Hello World!", 0, 50);
} else {
offscreen.drawString("khushbu", 2, 50);
}
initDone = true;
g.drawImage(buffImage, 0, 0, this);
} catch (Exception e) {
e.printStackTrace();
}
}
/** Handle the key typed event from the text field. */
public void keyTyped(KeyEvent e) {
}
/** Handle the key pressed event from the text field. */
public void keyPressed(KeyEvent e) {
String s;
offscreen.setColor(owner.fore);
offscreen.setFont(fn);
for (int i = counter; i < counter + 25; ++i) {
s = Integer.toString(i);
offscreen.drawString(s, 3, i * chh);
offscreen.drawLine(10, i * chh, 160, i * chh);
}
//owner.s.setScrollPosition(0, counter * 16);
counter = counter + 25;
repaint();
}
/** Handle the key released event from the text field. */
public void keyReleased(KeyEvent e) {
}
public boolean keyDown(Event e, int k) {
String s;
offscreen.setColor(owner.fore);
offscreen.setFont(fn);
for (int i = counter; i < counter + 25; ++i) {
s = Integer.toString(i);
offscreen.drawString(s, 3, i * chh);
offscreen.drawLine(10, i * chh, 160, i * chh);
}
//owner.s.setScrollPosition(0, counter * 16);
counter = counter + 25;
repaint();
return true;
}
}
Can I set JPanel background transparent?if yes How?
Yes, just call setOpaque(false); on that JPanel. On the contrary, if you want the background to be painted, call setOpaque(true); on that panel.
Additional remarks:
public boolean action(Event e, Object arg) is Deprecated. Add the appropriate listeners instead.
Follow Java coding conventions and use an Uppercase letter for the first character of a class
You should almost never call getGraphics(); on a Component
Don't override public void paint(Graphics g) but protected void paintComponent(Graphics g). Don't forget to call super.paintComponent if you want the background to be painted
Why do you override reshape?
Why do you create an internal buffer? Swing already has built-in double buffering and they do a much better job.
If you overrode already paint() why do you also override update()? You are performing the same job twice.
Remove that gr class variable, it does not make any sense. When you use Graphics object, use the one provided as a parameter of the paintComponent method but don't keep a reference to it, as it will be disposed later.
counter does not need to be static. Try to avoid static as much as possible.
Try to avoid so much coupling between your classes. It makes your code harder to maintain and less predictable.
Next time, post an SSCCE with something else than an Applet (a JFrame, for example) unless the problem you are having really requires an Applet to be reproduced.