I have a problem with my code.
We have to code a Game called "Mühle" as our project for this semester.
My problem is, that I want to draw my game token on the field and it does not work although the tokens are added to the board and you can click them but they are not visible and I don't know what I can do.
This is the important part frow my GUI Class:
public class GUIMühle extends JFrame {
static JLabel spieler1, spieler2;
static JFrame frame;
static JButton[] button;
static JButton btnReset;
static int x, y;
static int gewinner = 0;
static int player = 2;
static Buttons[] buttons;
static Steine[] steine1;
static Steine[] steine2;
public GUIMühle(){
InitUI();
}
private void InitUI(){
MouseEvents ME = new MouseEvents();
frame = new JFrame("Mühle");
frame.setSize(960, 540);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.CYAN);
frame.setResizable(false);
DrawSpielbrett spielbrett = new DrawSpielbrett();
spielbrett.setBounds(0,0,960,540);
spielbrett.setVisible(true);
frame.add(spielbrett);
spieler1 = new JLabel("Spieler 1");
spieler1.setBounds(590, 50, 150, 35);
spieler1.setFont(new Font("Arial", Font.BOLD, 30));
frame.add(spieler1);
spieler2 = new JLabel("Spieler 2");
spieler2.setBounds(785, 50, 150, 35);
spieler2.setFont(new Font("Arial", Font.BOLD, 30));
frame.add(spieler2);
// Spielsteine
steine1 = Steine.Erstellen(Color.white, 9, 665, 85);
steine2 = Steine.Erstellen(Color.black, 9, 860, 85);
DrawSteine[] drawSteine1 = new DrawSteine[9];
DrawSteine[] drawSteine2 = new DrawSteine[9];
for(int i = 0; i < steine1.length; i++){
steine1[i].setBounds(steine1[i].getX(),steine1[i].getY(),30,30);
steine1[i].addMouseListener(ME);
steine1[i].setVisible(true);
frame.add(steine1[i]);
}
for(int i = 0; i < steine2.length; i++){
steine2[i].setBounds(860,85+(i*32),30,30);
steine2[i].addMouseListener(ME);
frame.add(steine2[i]);
}
And this is the part from my game token class:
public class Steine extends JLabel{
private Color farbe;
private int x;
private int y;
public Steine(Color farbe, int x, int y){
this.farbe = farbe;
this.x = x;
this.y = y;
}
public static Steine[] Erstellen(Color farbe, int anzahl, int x, int y){
Steine[] steine = new Steine[anzahl];
for(int i = 0; i < steine.length; i++){
steine[i] = new Steine(farbe,x,y);
y = y + 32;
}
return steine;
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(this.farbe);
g.fillOval(this.x, this.y, 30, 30);
repaint();
}
/*public static void DrawSteine(Steine stein){
GUIMühle.frame.add(stein);
}*/
public Color getFarbe() {
return this.farbe;
}
#Override
public int getX() {
return this.x;
}
public void setX(int x) {
this.x = x;
}
#Override
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
I hope somebody can help me with this problem.
Thank you in advance.
Related
I have a panel which extends JPanel and overrides method paintComponent(Graphics g) which draw some squares.
public class Painter extends JPanel{
private static final Color orange = new Color(225, 95, 0);
private Block[][] blocks;
private int sizeBlock;
public Painter() {
this.setBackground(Color.WHITE);
}
public void setBlocks(Block[][] blocks) {
this.blocks = blocks;
}
public void setSizeBlock(int size) {
this.sizeBlock = size;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(Block[] cols : blocks) {
for(Block block : cols) {
switch(block.getType()) {
case Block.wall: {
paintBlockLineBorder(g, block.getX()*(sizeBlock-1),
block.getY()*(sizeBlock-1), orange);
break;
}
default: {break;}
}
}
}
}
private void paintBlockLineBorder(Graphics g, int x, int y, Color color) {
//background
g.setColor(color);
g.fillRect(x, y, sizeBlock, sizeBlock);
//border
g.setColor(Color.BLACK);
g.drawRect(x, y, sizeBlock-1, sizeBlock-1);
}
}
I add this JPanel (Painter) into other JPanel (painterPanel) which is added to a JFrame with layout GridBagLayout.
The result is not how I want:
This is what I want:
Here is a little use-case which reproduces the problem:
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new GridBagLayout());
mainFrame.setBounds(100, 100, 500, 400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 0; gbc.gridy = 0;
gbc.weighty = 1; gbc.weightx = 1;
JPanel painterPanel = new JPanel();
painterPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainFrame.add(painterPanel, gbc);
Painter apainter = new Painter();
painterPanel.add(apainter);
Block[][] ablock = new Block[2][2];
ablock[0][0] = new Block(0, 0, Block.wall);
ablock[0][1] = new Block(0, 1, Block.wall);
ablock[1][0] = new Block(1, 0, Block.wall);
ablock[1][1] = new Block(1, 1, Block.wall);
apainter.setBlocks(ablock);
apainter.setSizeBlock(25);
apainter.repaint();
mainFrame.setVisible(true);
}
and here is Block class:
public class Block {
public static final String wall = "wall";
private int x;
private int y;
private String type;
public Block(int x, int y, String type) {
this.x = x;
this.y = y;
this.type = type;
}
//getters & setters
}
Why is my Painter not completely visible?
Try the following :
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main{
public static void main(String[] args) throws InterruptedException{
JFrame mainFrame = new JFrame();
Block[][] ablock = new Block[2][2];
ablock[0][0] = new Block(0, 0, Block.wall);
ablock[0][1] = new Block(0, 1, Block.wall);
ablock[1][0] = new Block(1, 0, Block.wall);
ablock[1][1] = new Block(1, 1, Block.wall);
Painter apainter = new Painter();
mainFrame.add(apainter);
apainter.setBlocks(ablock);
apainter.setSizeBlock(25);
mainFrame.pack();
mainFrame.setVisible(true);
}
}
class Painter extends JPanel{
private static final Color orange = new Color(225, 95, 0);
private Block[][] blocks;
private int sizeBlock;
public Painter() {
setBackground(Color.WHITE);
setBorder(BorderFactory.createLineBorder(Color.black));
setPreferredSize(new Dimension(400, 300));
}
public void setBlocks(Block[][] blocks) {
this.blocks = blocks;
}
public void setSizeBlock(int size) {
sizeBlock = size;
//you may want to update Preferred Size
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(Block[] cols : blocks) {
for(Block block : cols) {
switch(block.getType()) {
case Block.wall: {
paintBlockLineBorder(g, block.getX()*(sizeBlock-1),
block.getY()*(sizeBlock-1), orange);
break;
}
default: {break;}
}
}
}
}
private void paintBlockLineBorder(Graphics g, int x, int y, Color color) {
//background
g.setColor(color);
g.fillRect(x, y, sizeBlock, sizeBlock);
//border
g.setColor(Color.BLACK);
g.drawRect(x, y, sizeBlock-1, sizeBlock-1);
}
}
class Block {
public static final String wall = "wall";
private final int x;
private final int y;
private final String type;
public Block(int x, int y, String type) {
this.x = x;
this.y = y;
this.type = type;
}
int getX() {return x; }
int getY() {return y; }
String getType() { return type;}
}
Don't hesitate to ask for clarifications as needed.
Also consider making a grid using GridLayout : 1 2
At advice of #CarlosHeuberger I overrided getPreferredSize, getMinimumSize and getMaximumSize which return a Dimension with values based on lengths of blocks and value of sizeBlock
I'm having a hard time to figure out why this moving rectangle is stopped right in the middle of the Jpanel. The Timer is not stopped, seems there is a boundary in the middle. Anyone could explain it for me please? and how can I make it move the whole way (800)?
here is my code:
public class TestDemo extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private int x;
private int y;
Timer timer;
TestDemo() {
x = 0;
y = 0;
this.setBackground(Color.BLACK);
timer = new Timer(10, this);
timer.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.scale(1, 1);
g2d.setPaint(Color.RED);
g2d.fill(new Rectangle2D.Double(getX(), getY(), 20, 20));
}
public void actionPerformed(ActionEvent e) {
setX(getX() + 1);
repaint();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving star");
JPanel testDemo = new TestDemo();
testDemo.setSize(800, 200);
frame.add(testDemo);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
The code is overriding methods that already exist and are used for other purposes. That is the main problem.
For custom painting any JComponent, use paintComponent(..) rather than paint(..)
Here is the (working) code with both changes implemented.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class TestDemo extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private int x1;
private int y1;
Timer timer;
TestDemo() {
x1 = 0;
y1 = 0;
this.setBackground(Color.BLACK);
timer = new Timer(10, this);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.scale(1, 1);
g2d.setPaint(Color.RED);
g2d.fill(new Rectangle2D.Double(getX1(), getY1(), 20, 20));
}
public void actionPerformed(ActionEvent e) {
setX1(getX1() + 1);
repaint();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving star");
JPanel testDemo = new TestDemo();
testDemo.setSize(800, 200);
frame.add(testDemo);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getY1() {
return y1;
}
public void setY1(int y1) {
this.y1 = y1;
}
}
Good day, I'm new to StackOverflow and Java programming. I currently have a school project that needs multi threading and I just need your advice on how to fix my code. I have spent too much time looking for answers on how to create a moving multiple images using a thread. I knew I'm almost near to find the solution but I'm running out of time as the submission is fast approaching. I believed I'll be more efficient if I seek help from somehow who knows better in Java.
Many thanks in advance.
Below is my current code, and it seems that image is flickering while moving.
// Bounce.java
import javax.swing.JFrame;
public class Bounce {
public static void main(String args[]) {
myBall s = new myBall(10, 20, 2, 2);
myBall s1 = new myBall(100, 10, 2, 2);
myBall s2 = new myBall(40, 10, 2, 2);
JFrame f = new JFrame();
f.add(s);
f.add(s1);
f.add(s2);
f.setVisible(true);
f.setSize(600, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Moving Ball");
}
}
The next code is in separate file.
// myBall.java
import java.awt.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class myBall extends JPanel implements Runnable {
private Thread animator;
int x = 0, y = 0, velX = 2, velY = 2;
Timer t;
public myBall(int x, int y, int velX, int velY) {
JFrame jf = new JFrame();
jf.setSize(600,400);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(this);
jf.setVisible(true);
this.x = (int )(Math.random() * 560);
this.y = (int )(Math.random() * 360);
this.velX = velX;
this.velY = velY;
}
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
g2.fill(ellipse);
}
public void cycle() {
if(x < 0 || x > 560) {
velX = -velX;
}
if(y < 0 || y > 360) {
velY = -velY;
}
x += velX;
y += velY;
System.out.println(x);
}
#Override
public void run() {
while(true) {
for (int i = 0; i < 600; i++) {
cycle();
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
}
}
Here you go. I normally don't do this, but you asked nicely and your code was pretty clean, so I assumed you been working a lot on it.
public class Start {
public static void main(String args[]) {
JFrame f = new JFrame();
Gui gui = new Gui();
gui.addBalls();
f.add(gui);
f.setSize(600, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Moving Ball");
f.setVisible(true);
}
}
Class GUI:
public class Gui extends JPanel implements Runnable {
private Thread animator;
int x = 0, y = 0, velX = 2, velY = 2;
Timer t;
ArrayList<myBall> myBalls = new ArrayList<>();
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (myBall ball: myBalls) {
int x = ball.getX();
int y = ball.getY();
Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
g2.fill(ellipse);
}
}
public void cycle() {
for (myBall ball: myBalls) {
int x = ball.getX();
int y = ball.getY();
if(x < 0 || x > 560) {
ball.reverseX();
}
if(y < 0 || y > 360) {
ball.reverseY();
}
ball.move();
System.out.println(x);
}
}
#Override
public void run() {
while(true) {
for (int i = 0; i < 600; i++) {
cycle();
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
}
public void addBalls() {
for (int i = 0; i < 4; i++) {
int x = (int )(Math.random() * 560);
int y = (int )(Math.random() * 360);
int velX = -5;
int velY = 5;
myBalls.add(new myBall(x, y, velX, velY));
}
}
}
Class Ball:
public class myBall {
int x;
int y;
int velX;
int velY;
public myBall(int x, int y, int velX, int velY) {
this.x = (int )(Math.random() * 560);
this.y = (int )(Math.random() * 360);
this.velX = velX;
this.velY = velY;
}
public void move() {
x+=velX;
y+=velY;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void reverseX() {
velX = -velX;
}
public void reverseY() {
velY = -velY;
}
}
ok so I created a method that randomly moves an enemy icon, and I used a Swing timer to make it constantly repeat and update every second or so, but the problem is the icon isn't moving it's just staying at the position, I added a print method to display my random numbers, and they are being created and displayed properly, but my enemy is not moving, any help is greatly appreciated :) and the ImageIcon for the bluespell class is a method that jus returns a regular ImageIcon there's nothing wrong with that method ha
public class BlueSpell extends WizardBattleGrid{
private int BlueSpellx;
private static int BlueSpelly;
private ImageIcon Blue;
WizardBattleRunner wbr = new WizardBattleRunner();
Timer timer;
public BlueSpell(int x, int y, ImageIcon BlueSpell){
BlueSpellx = x;
BlueSpelly = y;
Blue = BlueSpell;
}
public int getx(){
return BlueSpellx;
}
public int gety(){
return BlueSpelly;
}
public ImageIcon getIcon(){
return Blue;
}
public int changex(int x){
BlueSpellx = x;
return x;
}
public int changey(int y){
BlueSpelly = y;
return y;
}
public void shootSpell(){
final BlueSpell b = new BlueSpell(GoodGuy.getx(), GoodGuy.gety() +1, BlueSpellWizard());
int delay = 60;
timer = new Timer(delay,new ActionListener(){
public void actionPerformed(ActionEvent e){
if(b.gety() != 19){
WizardCells[b.getx()][b.gety()].setIcon(null);
WizardCells[b.getx()][b.changey(b.gety()+1)].setIcon(b.getIcon());
}
else{
WizardCells[b.getx()][b.gety()].setIcon(null);
b.changex(GoodGuy.getx());
b.changey(GoodGuy.gety() +1);
timer.stop();
}
}
});
timer.start();
}
}
WizardCells are in my Grid class here they are:
public class WizardBattleGrid extends GameWindowWizard {
public static JLabel[][] WizardCells = new JLabel [20][20];
public static JPanel WizardPanel = new JPanel(new GridLayout(20, 20, 0, 0));
static BufferedImage cursorimage = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
static Cursor blankcursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorimage, new Point(0, 0), "blank cursor");
public static void CreateGrid(){
for(int i=0; i<WizardCells.length; i++ ){
for(int j=0; j<WizardCells[i].length; j++){
JLabel label = new JLabel();
WizardCells[i][j] = label;
}
}
for(int i=0; i<WizardCells.length; i++){
for(int j=0; j<WizardCells[i].length;j++){
WizardPanel.add(WizardCells[i][j]);
}
}
WizardCells[10][0].setIcon(GoodGuyWizardIcon());
WizardPanel.setOpaque(true);
WizardPanel.setBackground(Color.DARK_GRAY);
WizardPanel.setCursor(blankcursor);
gameWindow.add(WizardPanel);
}
}
I want to let a ball bounce in a screen with the following code. The problem is that it only moves when I Resize the frame. So i have my paintcomponent in my panel method. While my thread is running i run a loop where i move the ball, sleep the thread and repaint.
The ball is only moving when i resize the frame.
Can anyone help me?
public class SpelPaneel extends JPanel {
private JLabel spelLabel;
private JPanel spelPaneel;
private Image background;
private Bal bal;
public SpelPaneel() {
spelPaneel = new JPanel();
spelLabel = new JLabel("spel");
add(spelLabel);
try {
background = ImageIO.read(new File("src/Main/images/background2.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
bal = new Bal(spelPaneel, 50, 50, 15);
bal.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background, 0, 0, getWidth(), getHeight(), null);
bal.teken(g, Color.red);
}
}
class Bal extends Thread {
private JPanel paneel;
private int x, y, grootte;
private int dx, dy;
private boolean doorgaan;
public Bal(JPanel paneel, int x, int y, int grootte) {
this.paneel = paneel;
this.grootte = grootte;
this.x = x;
this.y = y;
dy = 2;
doorgaan = true;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void run() {
while (doorgaan) {
paneel.repaint();
slaap(10);
verplaats();
}
}
public void teken(Graphics g, Color kleur) {
g.setColor(kleur);
g.fillOval(x, y, 15, 15);
}
public void verplaats() {
if (x > 335 || x < 50) {
dx = -dx;
}
if (y > 235 || y < 50) {
dy = -dy;
}
x += dx;
y += dy;
setX(x);
setY(y);
}
private void slaap(int millisec) {
try {
Thread.sleep(millisec);
} catch (InterruptedException e) {
}
}
}
spelPaneel = new JPanel(); //
Your SpelPaneel class extends JPanel so there is no need to create another panel. The above line of code just creates a JPanel in memory but does nothing with it.
bal = new Bal(spelPaneel, 50, 50, 15);
Then you create your Bal Thread and pass this dummy panel to it and later attempt to do a repaint on this dummy panel.
Intead I would guess the code should be:
bal = new Bal(this, 50, 50, 15);
since "this" refers to the actual instance of the SeplPaneel that you created.