hello i am having trouble trying to understand swing timers. to help me could someone show me a simple flickering animation? i have looked arround on the internet but still dont fully understand how they work. it would be so helpful if someone could give me an example like this:
say if i created a circle:
g.setColor(colors.ORANGE);
g.fillOval(160, 70, 50, 50);
how could i then use a swing timer to change the color from orange to say Gray using a swing timer with a delay?
thank you so much for helping me understand :)
First of all, you wouldn't hard-code your color use like this:
g.setColor(colors.ORANGE);
g.fillOval(160, 70, 50, 50);
Since this prevents all ability to change the color's state. Instead use a class field to hold the Color used, and call it something like ovalColor:
private Color ovalColor = SOME_DEFAULT_COLOR; // some starting color
And then use that color to draw with:
g.setColor(ovalColor);
g.fillOval(160, 70, 50, 50);
I'd then give my class an array of Color or ArrayList<Color> and an int index field:
private static final Color[] COLORS = {Color.black, Color.blue, Color.red,
Color.orange, Color.cyan};
private int index = 0;
private Color ovalColor = COLORS[index]; // one way to set starting value
Then in the Swing Timer's ActionListener I'd increment the index, I'd mod it by the size of the array or of the ArrayList, I'd get the Color indicated by the index and call repaint();
index++;
index %= COLORS.length;
ovalColor = COLORS[index];
repaint();
Also here's a somewhat similar example.
Also please look at the Swing Timer Tutorial.
maybe this would help:
public class object{
Color color = Color.GREEN;
Timer timer;
public object() {
timer = null;
timer = new Timer(5000, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (color.equals(Color.GREEN)) {
color = Color.RED;
timer.setDelay(2000);
} else {
color = Color.GREEN;
timer.setDelay(8000);
}
repaint();
}
});
timer.start();}}
I think a paint method would work.like this:
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.green);
g.filloval(30,40,50,50);
}
Related
I'm pretty new to Java and the GUI world. Right now I'm trying to create a really basic space shooter. To create it I started creating a JFrame, in which I've later on put a personal extension of a JPanel called GamePanel, on which I'm now trying to display all my components. Until here it's all pretty clear, the problem comes now: I have my GamePanel in which I display my player, and on the KeyEvent of pressing S the player should shoot the Bullets. I've managed the bullets as an Array, called Shooter[], of Bullet Objects, created by myself this way:
public class Bullet implements ActionListener{
Timer Time = new Timer(20, this);
private int BulletY = 430;
public int PlayerX;
public Rectangle Bound = new Rectangle();
public Bullet(int playerx) {
this.PlayerX = playerx;
Time.start();
}
public void draw(Graphics g){
g.setColor(Color.RED);
g.fillRect(PlayerX + 2, BulletY, 3, 10);
g.dispose();
}
#Override
public void actionPerformed(ActionEvent e) {
if (Time.isRunning()) {
BulletY = BulletY - 5;
Bound = new Rectangle (PlayerX + 2, BulletY, 3, 10);
}
}
}
I thought that calling the draw method in the GamePanel's paint() method would have allowed me to display both all the bullets shot and the player. What actually happens is that at the start it seems allright, but when I press S the player disappears and just one bullet is shot. Can you explain me why? This is how my paint() method looks like:
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, 500, 500);
for(int i = 0; i < BulletsCounter; i++) {
Shooter[i].draw(g);
}
g.setColor(Color.RED);
g.fillRect(PlayerX, PlayerY, 20, 20);
//System.out.println("Here I should have painted the player...");
g.dispose();
}
BulletsCounter is a counter I've created to avoid any NullPointerExceptions in painting the whole array, it increases when S is pressed and so another bullet of the array is initialized and shot.
Thank you for your patience, I'm new to the site, so warn me for any mistake.
You've several significant problems, the biggest given first:
You're disposing a Graphics object given to you by the JVM. Never do this as this will break the painting chain. Instead, only dispose of a Graphics object that you yourself have created.
You're drawing within paint which is not good for several reasons, but especially bad for animation since you don't have automatic double buffering of the image
You don't call the super painting method within your override and thus don't allow the JPanel to do house-keeping painting.
Recommendations:
Don't dispose of the Graphics object, not unless you, yourself, create it, for example if you extract one from a BufferedImage.
Override the JPanel's paintComponent method, not its paint method to give you double buffering and smoother animation.
And call super.paintComponent(g) first thing in your override to allow for housekeeping painting
I'm writing a simulation in Java in Netbeans, and the actual non-graphical coding is mostly done. However, I'd like to do a graphical implementation where I use icons to represent the variables changing in the simulation.
The simulation simulates trucks driving along roads, and I'd like an icon to represent every truck. The code shows each truck and each road as a separate object, each with their own attributes, but only a few of the attributes need to be modeled in the graphical implementation. For instance, the position of each truck is an attribute of the road, showing how far along the road the truck has traveled.
What is the easiest way to model this in a graphical interface? I assume I need to assign an icon to a graphical structure in Netbeans and then have it update itself according to the distance attribute of the road, but I have no idea how to approach this.
Any help will be appreciated.
Using the Graphics class, you can draw the roads, the cars(using images), and animate with a Swing Timer.
To draw the cars you can use paint the images onto the screen
public class Map extends JPanel {
BufferedImage car1;
BufferedImage car2;
BufferedImage car3;
public Map(){
try {
car1 = ImageIO.read(getClass().getResource("somecarimage.png"));
car3 = ImageIO.read(getClass().getResource("somecarimage.png"));
car3 = ImageIO.read(getClass().getResource("somecarimage.png"));
}
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
// use the drawImage method
g.drawImage(car1, xLocation, yLocation, height, width, this);
g.drawImage(car2, xLocation, yLocation, height, width, this);
g.drawImage(car2, xLocation, yLocation, height, width, this);
}
}
As you can see, I drew three car onto the screen. You can use your class with the data as the xLocation and yLocation
If you want to animate the cars, you can use a Swing Timer
Timer timer = new Timer(100, new ActionListener(){ // causes an action every 100 millis
public void actionPerformed(ActionEvent e){
// change the xLocation and yLocation of each car
car1.xLocation += 5;
car1.yLocation += 5;
car2.xLocation += 5;
car2.yLocation += 5;
car3.xLocation += 5;
car3.yLocation += 5;
repaint();
}
});
timer.start();
You can have an if statement somewhere in the actionPerformed telling the timer when to stop.
Javadocs and tutorials
Timer javadoc | Timer tutorial | Graphics javadoc | Graphics tutorial
Dear wonderful people of stackoverflow
A group of my friends are attempting to make a level editor in Java.
We have a Jpanel instead of a Jframe and we are trying to put small images onto the Jpanel from a filepath saved as a string. In the end we want a list of images that you can just drop on. So far we have tried a few methods with no luck.
We can load the images, however we can't get these images to actually display, What would be the best means of solving said problem?
below is a sample of what we have so far.
EnemyPlacementGrid = new JPanel();
EnemyPlacementGrid.addMouseListener(new MouseAdapter() {
//#Override
public int mouseX;
public int mouseY;
public void mouseClicked(MouseEvent arg0) { //what happens when you click in the EnemyPlacementGrid
System.out.println("Correct Area for placement");
mouseX = arg0.getX();
mouseY = arg0.getY();
//System.out.println("X:" + mouseX + ", Y:" + mouseY );
Enemy newEnemy = workingEnemy.cloneSelf();
newEnemy.setLocation(mouseX, mouseY);
System.out.println("newEnemy object: " + newEnemy);
System.out.println(newEnemy.weaponList);
currentWave.addEnemy(newEnemy);
System.out.print(currentLevel);
}
});
Any and all help is greatly appreciated.
UPDATE:
As of now I have an image appearing, however I can't update said image. Note code below:
public void run() {
try {
BufferedImage img = ImageIO.read(new File(IMG_PATH));
ImageIcon icon = new ImageIcon(img);
WaveScreen frame = new WaveScreen();
JPanel panel = (JPanel)frame.getContentPane();
JLabel label = new JLabel();
label.setIcon(new ImageIcon("images/map_on.png"));// your image here
panel.add(label);
frame.setVisible(true);
panel.add(label);
panel.repaint();
} catch (Exception e) {
e.printStackTrace();
}
update, method tried from comments:
Graphics2D g = null;
Graphics2D g2 = (Graphics2D)g;
Image imageVariable = new ImageIcon("images/map_on.png").getImage();
g.drawImage(imageVariable, mouseX, mouseY, null);
Well, i'd say to try using Graphics, meaning you need to override the paint method; i'd recommend that you put the mouseX and mouseY as global variables though…
// creating global image variable for use later
Image imageVariable = new ImageIcon("image path").getImage();
public void paintComponent(Graphics g) {
// here you could either create a Graphics2D object
// Graphics2D g2 = (Graphics2D)g;
// or you could use the g parameter as it is, doesn't matter.
// use the global variable for the image to be drawn onto the screen
// use the global value of the mouseX and mouseY for where you click the mouse
// to place the image, and this should be it
g.drawImage(imageVariable, mouseX, mouseY, null);
}
Hope this helps!
If the game is simple, user2277872's solution will work and you can use graphics2D from java. However, if you are planning on a more sophisticated game (lots of interaction, lots of textures), then the default Java framework for 2D graphics will prove to be too slow.
If you are planning on such a game, I can highly recommend either learning OpenGL or using an existing framework for graphics, such as
JMonkeyEngine (http://jmonkeyengine.com/)
or
Slick (http://slick.cokeandcode.com/index.php)
More information: What should I use to display game graphics?
i am developing an application in which i need to set two button in HorizontalFieldManage. where one Bitmap should stay left and another LabelField should stay center at horizontally. here i have tried many time but cant able to set first Bitmap at Left so can you please help me out from this..
Here is my Code ::
VerticalFieldManager VFM = new VerticalFieldManager(USE_ALL_WIDTH){
public void paint(Graphics g) {
g.setBackgroundColor(Color.WHITE);
g.clear();
super.paint(g);
}
};
HorizontalFieldManager HFM = new HorizontalFieldManager(FIELD_HCENTER){
public void paint(Graphics g) {
g.setBackgroundColor(Color.WHITE);
g.clear();
super.paint(g);
}
};
Bitmap logom1;
logom1 = Bitmap.getBitmapResource("logo48X48.png");
BitmapField imgField = new BitmapField(logom1,Field.FIELD_LEFT);
LabelField RegistrationLbl = new LabelField("Registration",FIELD_HCENTER | FIELD_BOTTOM);
FontFamily fontFamily[] = FontFamily.getFontFamilies();
Font font = fontFamily[1].getFont(FontFamily.CBTF_FONT, 20);
font = fontFamily[1].getFont(Font.BOLD, 25);
RegistrationLbl.setFont(font);
HFM.add(imgField);
HFM.add(RegistrationLbl);
VFM.add(HFM);
add(VFM);
Signare's general solution could work, but the left margin wasn't quite right. The only calls you need to add are these (split into two lines for clarity), before adding your label to the HFM object:
int labelX = (Display.getWidth() - RegistrationLbl.getPreferredWidth()) / 2;
RegistrationLbl.setMargin(0, 0, 0, labelX - imgField.getPreferredWidth());
This assumes the class (Manager) that this is in takes up the full screen width (Display.getWidth()).
Read this for a good description of what margin is.
Also, note that setMargin() was undocumented in the APIs before 6.0, but I believe it was actually available (but, undocumented) back to OS 4.5 or so.
Edit: by the way, you are assigning your font object, and then immediately assigning it to something else. That doesn't look right either, although it doesn't affect the problem centering the label.
Another Edit: as illustrated by Rupak's comment, this code only works if you have a fixed orientation display. If the label is supposed to center itself again on device orientation change, then you need more than this. Please just add more clarification to the question, if that's needed, and someone will help!
try this (This is not a correct way)-
HorizontalFieldManager VFM = new HorizontalFieldManager(){
public void paint(Graphics g) {
g.setBackgroundColor(Color.WHITE);
g.clear();
super.paint(g);
}
};
HorizontalFieldManager LogoHFM = new HorizontalFieldManager(FIELD_LEFT);
Bitmap logom1;
logom1 = Bitmap.getBitmapResource("logo48X48.png");
BitmapField imgField = new BitmapField(logom1);
LogoHFM.add(imgField);
LabelField RegistrationLbl = new LabelField("Registration",FIELD_HCENTER);
FontFamily fontFamily[] = FontFamily.getFontFamilies();
Font font = fontFamily[1].getFont(FontFamily.CBTF_FONT, 20);
font = fontFamily[1].getFont(Font.BOLD, 25);
RegistrationLbl.setFont(font);
RegistrationLbl.setMargin(0,0,0,(Display.getWidth()-logom1.getWidth())/4);
VFM.add(LogoHFM);
VFM.add(RegistrationLbl);
add(VFM);
How can I mousedrag different BufferedImages in Java2D?
For instance, if I have ten or more images, how can I move that images which my mouse is over?
Now I'm importing an BufferedImage with
BufferedImage img = new BufferdImage(new File("filename"));
And I'm painting this with Graphics2D with
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.drawImage(img, x1, y1, null);
g2d.drawImage(img2, x2, y2,null);
}
Everytime I'm moving on a image I'm repaint()-ing the entire screen.
My mousemove class is as follows
class MouseMotionHandler extends MouseMotionAdapter {
#Override
public void mouseDragged(MouseEvent e) {
x1 = e.getX() - (img.getWidth() / 2);
y1 = e.getY() - (img.getHeight() / 2);
repaint();
}
}
With this method I'm able to "drag" one picture, but what to do when I will drag more individually?
Use the BufferedImage to create an ImageIcon which you use to create a JLabel. Then you add the JLabel to the panel that uses a null layout. No custom painting code is required to do this.
Now if you want to drag the label around you can use the Component Mover.
You can try making a custom component that contains only a single image. Along with your painting and mouse motion handling code, the component overrides the contains method so that it returns true only if the coordinates are within the image.
These components are then stacked in a JLayeredPane, (hopefully) only moving the images that the mouse is on top of.
From what you ask I suppose that your current repainting logic is global. You need to apply it to every image you have. So, if you for instance display every image in JPanel attach MouseMotionListener to every such panel and make this logic happen in JPanel.
If you post more code - especially of the component you show your images in - I will be able to go into more details.
Here's is a simple example that implements dragging for either single- or multiple-selections. The object Node would correspond roughly to your object Card.
Addendum: Also considered the Overlap Layout mentioned in this answer to a related question. Instead of List<Node>, your program would manage a List<Card>, where each Card is a JLabel having a card image.
I should make tree arrays:
one for the x-values
one for the y-values
one for the BufferedImages
So, something like this:
int[] xValues = new int[10];
int[] yValues = new int[10];
BufferedImage[] imgs = new BufferedImage[10];
Then the
class MouseMotionHandler extends MouseMotionAdapter {
#Override
public void mouseDragged(MouseEvent e) {
for (int i = 0; i < 10; i++)
{
xValues[i] = e.getX() - (imgs[i].getWidth() / 2);
yValues[i] = e.getY() - (imgs[i].getHeight() / 2);
}
repaint();
}
}
Then paint them like this:
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
for (int i = 0; i < 10; i++)
{
g2d.drawImage(imgs[i], xValues[i], yValues[i], null);
}
}
I think something like this is what you need.
Here's the code for my JLayeredPane init. My problem here is that my images don't show up...
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new java.awt.Dimension(500, 410));
layeredPane.setBorder(javax.swing.BorderFactory.createTitledBorder(
"Center deck"));
for(BufferedImage imgs : images){
JLabel label = new JLabel(new ImageIcon(imgs));
layeredPane.add(label, JLayeredPane.DEFAULT_LAYER);
}
add(layeredPane);