java


I try to use the method repaint after paintComponent but its not work


First it will be a little longer because I want to show all the code I have done until now, so excuse me..
This is my first time in java.
I'm trying to build an aquarium with fish and jellyfish drawing and use threads.
When I try to add animal I want to paint it but without success, I built PaintComponent method but when I try to use repaint I can not draw..
What am I missing?
It looks that way, when I click on Add Animal window opens , I choose the values and after I click OK, need to draw the animal
I hope that the rest of what I did was okay .. thank you so much for helping!
paintComponent and repaint is at AquaPanel Class.
public class AquaFrame extends JFrame {
private AquaPanel mPanel;
private JLabel label1;
private ImageIcon icon;
private BufferedImage imag;
public AquaFrame() {
super("my Aquarium");
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(700, 600);
setResizable(false);
setVisible(true);
setLocationRelativeTo(null);
mPanel = new AquaPanel(getGraphics());
add(mPanel);
}
public void buildFrame(){
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu file = new JMenu("File");
menuBar.add(file);
JMenuItem exItem = new JMenuItem("Exit");
file.add(exItem);
exItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
JMenu background = new JMenu("Background");
menuBar.add(background);
JMenuItem blue = new JMenuItem("Blue");
blue.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mPanel.setBackground(Color.BLUE);
}
});
JMenuItem none = new JMenuItem("None");
none.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mPanel.setBackground(null);
}
});
JMenuItem image = new JMenuItem("Image");
image.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
imag = ImageIO.read(new File("aquarium_background.jpg"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
background.add(image);
background.add(blue);
background.add(none);
JMenu help = new JMenu("Help");
JMenuItem helpItem = new JMenuItem("help");
helpItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null,"GUI # Threads");
}
});
menuBar.add(help);
help.add(helpItem);
setVisible(true);
}
public void paint(Graphics g){
g.drawImage(imag, 0, 0, null);
}
public static void main(String[] args) {
AquaFrame mFrame = new AquaFrame();
mFrame.buildFrame();
}
}
/******************************************/
public class AquaPanel extends JPanel {
private JFrame infoTableFrame;
private JTable infoTable;
private Set<Swimmable > swimmables = new HashSet<Swimmable>();
private AddAnimalDialog animalDialog;
private int totalEatCounter;
private Graphics g;
public AquaPanel(Graphics g) {
this.g = g;
totalEatCounter = 0;
infoTableFrame = new JFrame();
infoTableFrame.setVisible(false);
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.PAGE_END;
constraints.weighty = 1;
JButton btAdd = new JButton("Add Animal");
btAdd.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (swimmables.size() >= 5)
{
JOptionPane.showMessageDialog(null, "You can't have more than 5 animals at the same time.");
}
else
{
animalDialog = new AddAnimalDialog(AquaPanel.this);
animalDialog.setVisible(true);
}
}
});
JButton btSleep = new JButton("Sleep");
btSleep.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Swimmable swimmable : swimmables)
{
swimmable.setSuspend();
}
}
});
JButton btWakeup = new JButton("Wake Up");
btWakeup.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Swimmable swimmable : swimmables)
{
swimmable.setResume();
}
}
});
JButton btRst = new JButton("Reset");
btRst.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Swimmable swimmable : swimmables)
{
swimmable.kill();
}
swimmables.clear();
}
});
JButton btFood = new JButton("Food");
btFood.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (swimmables.size() > 0)
{
CyclicBarrier barrier = new CyclicBarrier(swimmables.size());
for (Swimmable swimmable : swimmables)
{
swimmable.setBarrier(barrier);
swimmable.setFood(true);
}
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(3));
g2.setColor(Color.red);
g2.drawArc(getWidth() / 2, getHeight() / 2 - 5, 10, 10, 30, 210);
g2.drawArc(getWidth()/2, getHeight()/2+5, 10, 10, 180, 270);
g2.setStroke(new BasicStroke(1));
}
}
});
JButton btInfo = new JButton("Info");
btInfo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showInfoTable();
}
});
JButton btExit = new JButton("Exit");
btExit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
add(btAdd,constraints);
add(btSleep,constraints);
add(btWakeup,constraints);
add(btRst,constraints);
add(btFood,constraints);
add(btInfo,constraints);
add(btExit,constraints);
}
public void showInfoTable(){
if (infoTableFrame.isVisible())
{
infoTableFrame.remove(infoTable);
infoTableFrame.setVisible(false);
}
else
{
String[] col = {"Animal","Color","Size","Hor.speed","Ver.speed","Eat counter"};
String[][] data = new String[swimmables.size()][col.length];
int i=0;
for (Swimmable swimmable : swimmables)
{
data[i][0] = swimmable.getAnimalName();
data[i][1] = swimmable.getColor();
data[i][2] = "" + swimmable.getSize();
data[i][3] = "" + swimmable.getHorSpeed();
data[i][4] = "" + swimmable.getVerSpeed();
data[i][5] = "" + swimmable.getEatCount();
++i;
}
infoTable = new JTable(data, col);
//TODO - not overriding values
JScrollPane jPane = new JScrollPane(infoTable);
infoTableFrame.add(jPane, BorderLayout.CENTER);
infoTableFrame.setSize(300, 150);
infoTableFrame.setVisible(true);
}
}
public void addAnimal(Swimmable animal)
{
animal.setAquaPanel(this);
swimmables.add(animal);
animal.run();
//myrepaint();
/**********************************/
repaint();
/**********************************/
}
public void onEatFood(Swimmable eater)
{
eater.eatInc();
++totalEatCounter;
for (Swimmable swimmable : swimmables)
{
swimmable.setFood(false);
}
}
/*public void myrepaint()
{
for (Swimmable swimmable : swimmables)
{
swimmable.drawAnimal(g);
}
}*/
/************************************************/
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Swimmable swimmable : swimmables)
{
swimmable.drawAnimal(g);
}
}
/*********************************************/
}
public abstract class Swimmable extends Thread {
protected AquaPanel aquaPanel;
protected boolean isFood;
protected boolean isSuspended;
protected int horSpeed;
protected int verSpeed;
protected int x_dir, y_dir;
protected int eatCount;
protected CyclicBarrier barrier;
protected int x0, y0;
protected boolean isAlive;
public Swimmable() {
horSpeed = 0;
verSpeed = 0;
x_dir = 1;
y_dir = 1;
eatCount = 0;
}
public Swimmable(int hor, int ver) {
horSpeed = hor;
verSpeed = ver;
x_dir = 1;
y_dir = 1;
eatCount = 0;
}
#Override
public void run() {
isAlive = true;
while (isAlive) {
try {
sleep(10);
if (isSuspended)
{
wait();
}
else
{
if (isFood)
{
barrier.await();
updateFrontsTowardsFood();
if (isNearFood())
{
aquaPanel.onEatFood(this);
}
}
else
{
updateFronts();
}
//aquaPanel.myrepaint();
aquaPanel.repaint();
}
}
catch (Exception e)
{
//TODO - handle exception
}
}
}
public void kill()
{
isAlive = false;
}
public int getHorSpeed() {
return horSpeed;
}
public int getVerSpeed() {
return verSpeed;
}
public void setHorSpeed(int hor) {
horSpeed = hor;
}
public void setVerSpeed(int ver) {
verSpeed = ver;
}
abstract public int getSize();
abstract public String getColor();
public void setSuspend()
{
isSuspended = true;
}
public void setResume()
{
isSuspended = false;
}
public void eatInc()
{
++eatCount;
}
public int getEatCount()
{
return eatCount;
}
public void setBarrier(CyclicBarrier b)
{
barrier = b;
}
public void setFood(boolean isFood)
{
this.isFood = isFood;
}
public void setAquaPanel(AquaPanel panel)
{
aquaPanel = panel;
x0 = aquaPanel.getWidth() / 2;
y0 = aquaPanel.getHeight() / 2;
}
abstract public String getAnimalName();
abstract public void drawAnimal(Graphics g);
abstract protected void updateFronts();
abstract protected void updateFrontsTowardsFood();
abstract protected boolean isNearFood();
}
public class Fish extends Swimmable {
protected int x_front , y_front;
private int size;
private Color color;
public Fish(Color col, int sz, int hor, int ver) {
super(hor, ver);
size = sz;
color = col;
x_front = 0;
y_front = 0;
}
public void drawAnimal(Graphics g) {
g.setColor(color);
if (x_dir == 1) // fish swims to right side
{
// Body of fish
g.fillOval(x_front - size, y_front - size / 4, size, size / 2);
// Tail of fish
int[] x_t = { x_front - size - size / 4, x_front - size - size / 4, x_front - size };
int[] y_t = { y_front - size / 4, y_front + size / 4, y_front };
Polygon t = new Polygon(x_t, y_t, 3);
g.fillPolygon(t);
// Eye of fish
Graphics2D g2 = (Graphics2D) g;
g2.setColor(new Color(255 - color.getRed(),255 - color.getGreen(),255- color .getBlue()));
g2.fillOval(x_front-size/5, y_front-size/10, size/10, size/10);
//Mouth of fish
if(size>70)
g2.setStroke(new BasicStroke(3));
else if(size>30)
g2.setStroke(new BasicStroke(2));
else
g2.setStroke(new BasicStroke(1));
g2.drawLine(x_front, y_front, x_front-size/10, y_front+size/10);
g2.setStroke(new BasicStroke(1));
}
else // fish swims to left side
{
// Body of fish
g.fillOval(x_front, y_front - size / 4, size, size / 2);
// Tail of fish
int[] x_t = { x_front + size + size / 4, x_front + size + size / 4, x_front + size };
int[] y_t = { y_front - size / 4, y_front + size / 4, y_front };
Polygon t = new Polygon(x_t, y_t, 3);
g.fillPolygon(t);
// Eye of fish
Graphics2D g2 = (Graphics2D) g;
g2.setColor(new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue()));
g2.fillOval(x_front+size/10, y_front-size/10, size/10, size/10);
// Mouth of fish
if (size > 70)
g2.setStroke(new BasicStroke(3));
else if (size > 30)
g2.setStroke(new BasicStroke(2));
else
g2.setStroke(new BasicStroke(1));
g2.drawLine(x_front, y_front, x_front + size / 10, y_front + size / 10);
g2.setStroke(new BasicStroke(1));
}
}
public String getAnimalName() {
return "Fish";
}
public int getSize() {
return size;
}
public String getColor() {
if (color == Color.RED)
return "RED";
else if (color == Color.GREEN)
return "GREEN";
else if (color == Color.ORANGE)
return "ORANGE";
else
return "UNKNOWN";
}
protected void updateFronts()
{
x_front += x_dir * horSpeed;
y_front += y_dir * verSpeed;
if (x_front > x0*2 || x_front < 0)
x_dir *= -1;
if (y_front > y0*2 || y_front < 0)
y_dir *= -1;
}
protected void updateFrontsTowardsFood()
{
//TODO - copy from word
}
protected boolean isNearFood()
{
return ((Math.abs(x_front-x0) <= 5) && (Math.abs(y_front-y0) <= 5));
}
}
public class Jellyfish extends Swimmable {
private int x_front , y_front;
private int size;
private Color color;
public Jellyfish(Color col, int sz, int hor, int ver) {
super(hor, ver);
size = sz;
color = col;
x_front = 0;
y_front = 0;
}
public void drawAnimal(Graphics g) {
int numLegs;
if (size < 40)
numLegs = 5;
else if (size < 80)
numLegs = 9;
else
numLegs = 12;
g.setColor(color);
g.fillArc(x_front - size / 2, y_front - size / 4, size, size / 2, 0, 180);
for (int i = 0; i < numLegs; i++)
g.drawLine(x_front - size / 2 + size / numLegs + size * i / (numLegs + 1), y_front,
x_front - size / 2 + size / numLegs + size * i / (numLegs + 1), y_front + size / 3);
}
public String getAnimalName() {
return "Jellyfish";
}
public int getSize() {
return size;
}
public String getColor() {
if (color == Color.RED)
return "RED";
else if (color == Color.GREEN)
return "GREEN";
else if (color == Color.ORANGE)
return "ORANGE";
else
return "UNKNOWN";
}
public void updateFronts()
{
x_front += x_dir * horSpeed;
y_front += y_dir * verSpeed;
if (x_front > x0*2 || x_front < 0)
x_dir *= -1;
if (y_front > y0*2 || y_front < 0)
y_dir *= -1;
}
protected void updateFrontsTowardsFood()
{
//TODO - copy from word
}
protected boolean isNearFood()
{
return ((Math.abs(x_front-x0) <= 5) && (Math.abs(y_front-y0) <= 5));
}
}
public class AddAnimalDialog extends JDialog {
private JButton btOk, btCancel;
private JTextField tfSize, tfHspeed, tfVspeed;
private ButtonGroup groupType, groupColor;
private JRadioButton rbFish, rbJellyfish, rbRed, rbGreen, rbOrange;
JPanel panel;
public AddAnimalDialog(AquaPanel aquaPanel) {
this.setLayout(new FlowLayout());
panel = new JPanel();
panel.setLayout(new GridLayout(10, 20));
panel.add(new JLabel("Size(20-320): "));
panel.add(tfSize = new JTextField());
panel.add(new JLabel("Horizontal speed(1-10): "));
panel.add(tfHspeed = new JTextField());
panel.add(new JLabel("Vertical speed(1-10): "));
panel.add(tfVspeed = new JTextField());
panel.add(new JLabel("Type: "));
panel.add(new JLabel(" "));
panel.add(rbFish = new JRadioButton("fish"));
panel.add(rbJellyfish = new JRadioButton("jellyfish"));
panel.add(new JLabel("Color: "));
panel.add(new JLabel(" "));
panel.add(rbRed = new JRadioButton("Red"));
panel.add(rbGreen = new JRadioButton("Green"));
panel.add(rbOrange = new JRadioButton("Orange"));
// Group the radio buttons.
groupType = new ButtonGroup();
groupType.add(rbFish);
groupType.add(rbJellyfish);
rbFish.setSelected(true);
groupColor = new ButtonGroup();
groupColor.add(rbRed);
groupColor.add(rbGreen);
groupColor.add(rbOrange);
rbRed.setSelected(true);
panel.add(new JLabel(""));
panel.add(btOk = new JButton("OK"));
panel.add(btCancel = new JButton("Cancel"));
this.add(panel);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.pack();
this.btOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
int size = Integer.parseInt(tfSize.getText());
int hSpeed = Integer.parseInt(tfHspeed.getText());
int vSpeed = Integer.parseInt(tfVspeed.getText());
if (checkValues(size, hSpeed, vSpeed)) {
Color clr = Color.RED;
if (rbRed.isSelected()) {
clr = Color.RED;
} else if (rbGreen.isSelected()) {
clr = Color.GREEN;
} else if (rbOrange.isSelected()) {
clr = Color.ORANGE;
} else {
JOptionPane.showMessageDialog(null, "You must choose a color!");
}
if (rbFish.isSelected()) {
setVisible(false);
aquaPanel.addAnimal(new Fish(clr, size, hSpeed, vSpeed));
} else if (rbJellyfish.isSelected()) {
setVisible(false);
aquaPanel.addAnimal(new Jellyfish(clr, size, hSpeed, vSpeed));
} else {
JOptionPane.showMessageDialog(null, "You must choose animal type!");
}
}
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "One of the number values has wrong format, please check it");
}
}
});
this.btCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
System.out.println("Click the Close button if you want to stop adding windows");
}
});
}
private boolean checkValues(int size, int hspeed, int vspeed) {
if ((size > 320 || size < 20) || (hspeed < 1 || hspeed > 10) || (vspeed < 1 || vspeed > 10)) {
JOptionPane.showMessageDialog(null, "One of the values is out of bounds, please follow the restrictions.");
return false;
}
return true;
}
}
There are a number of basic problems...
The main problem is with your Swimmable run method, it is blocking the Event Dispatching Thread, preventing it from been able to respond to UI events, including repaint events. See Concurrency in Java for more details.
You should NEVER use getGraphics, apart from been able to return null, anything you paint to it is painted outside of the normal paint cycle and will painted over the next time component is repainted. See Painting in AWT and Swing and Performing Custom Painting for more details.
Your current approach won't scale well, the more fish you add, the more resources they will consume and will affect the ability for the program to keep up with all the different changes and repaint requests.
A better solution would be to have a single "update" loop which takes care of telling each of the Swimmables that it needs to update and then schedules a single repaint each cycle. Personally, I'd start with a Swing Timer as it "ticks" within the EDT, making it much safer to modify the state of the objects which the paintComponent method needs.
See How to use Swing Timers for more details
I would suggest having a look at this, which basically describes what you're trying to do and what I'm suggesting you should do instead
Try calling repaint in your JFrame class after calling the addAnimal method. There is also revalidate() method in there as well and their difference is in this article: Java Swing revalidate() vs repaint()

Related Links

calling a method thats located in main class from another class
Spring MVC - upload file is blocked by spring security [duplicate]
Run “Android update project --path .” return invalided number of parameters
Scanner object skipping
CriteriaBuilder in JPA with the method between
readLine for reading multiple lines without a loop?
Force Java runtime to use Jar in NSF instead of Jar on server of same name for XPages application
Java Array Questions
Can't execute servlet from JSP but can access from direct URL (mvc mysql tomcat)
Sending email using javamail with if else statement
How does the Spring forms .jsp tag library work?
NullPointerException on getReadableDatabase()
Trouble with createBufferStrategy in Java
Developing a record and playback tool using selenium webdriver
Unable to connect to server through wifi in android
Java MySQL query slower than expected

Categories

HOME
yii2
bluetooth
testng
pycharm
reserved
mfc
plot
relayjs
react-router
webstorm
android-4.4-kitkat
maven-3
microservices
google-project-tango
installshield
fingerprint
opengl-es-2.0
upload
user-input
rascal
vb.net-2010
clojurescript
openrefine
saxon
propel
beyondcompare
object-detection
accessor
zurb-foundation-6
captiveportal
cas
pingfederate
fgetcsv
minitab
libuv
gsoap
preg-match
fabric8
javascriptcore
kendo-ui-grid
stacked
event-driven
android-browser
mapzen
sas-jmp
apple-news
pebble-watch
directory-structure
windows-iot-core-10
color-profile
color-picker
probability-density
skobbler-maps
xml-attribute
player
contact-list
connect-by
holder.js
disque
superstack
revolution-r
historian
collapse
django-unittest
tarjans-algorithm
android-listview
map-projections
mdt
fpml
code-access-security
rdl
sgen
p4java
jubula
xceed-datagrid
java.nio.file
monomac
quantlib-swig
commoncrypto
blending
rabl
interface-orientation
limejs
free-variable
bluepill
qtkit
amazon-appstore
assembly-loading
window-management
data-loss
mod-auth
appender
lang
radcombobox
google-friend-connect
multi-tier
procedural-music
private-members

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App