I have created a matrix on java and I need to add two JButton "cancel" and "submit" below the matrix
This is my code but it miss the two JButton , need your help please .
public class matrice2 extends JFrame{
private static final long serialVersionUID = 1L;
private final int width;
private final int height;
private final JLabel[] horizon;
private final JLabel[] vertical;
private final JButton[][] centre;
//private final JButton[] VC;
private final ImageIcon ZERO = new ImageIcon("0.jpg");
private final ImageIcon ONE = new ImageIcon("1.jpg");
public matrice2(int width, int height) {
this.width = width;
this.height = height;
horizon = new JLabel[width];
vertical = new JLabel[height];
centre = new JButton[width][height];
initFrame();
fillContent();
this.setVisible(true);
}
private void initFrame() {
this.setSize(700, 700);
this.setTitle("Matrice du graphe");
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JLabel createColumnHeader(int x) {
horizon[x] = new JLabel("H" + (x + 1));
return horizon[x];
}
private JLabel createRowHeader(int y) {
vertical[y] = new JLabel("V" + (y + 1));
return vertical[y];
}
private JButton createCell(int x, int y) {
centre[x][y] = new JButton();
centre[x][y].addActionListener(new MatriceListener(this,x,y));
return centre[x][y];
}
public void fillContent() {
this.setLayout(new GridLayout(width+2, height+2));
this.add(new JLabel());
for (int x = 0; x < width; x++)
this.add(createColumnHeader(x));
for (int y = 0; y < height; y++) {
this.add(createRowHeader(y));
for (int x=0; x<width; x++)
this.add(createCell(x,y));
}
}
public void setIcon(int x, int y) {
centre[x][y].setIcon(ONE);
}
Change the fillContent() method:
public void fillContent() {
JPanel content = new JPanel();
content.setLayout(new GridLayout(width + 2, height + 2));
content.add(new JLabel());
for (int x = 0; x < width; x++) {
content.add(createColumnHeader(x));
}
for (int y = 0; y < height; y++) {
content.add(createRowHeader(y));
for (int x = 0; x < width; x++) {
content.add(createCell(x, y));
}
}
add(content, BorderLayout.CENTER);
JPanel buttons = new JPanel();
buttons.add(new JButton("Submit"));
buttons.add(new JButton("Cancel"));
add(buttons, BorderLayout.SOUTH);
}
Related
I have written a short game. In the existing implementation I have a GridBagLayout with buttons located as chess board. Each button occupies the whole grid. Game works fine. My next task is to change the board to be consist of hexagonal buttons, not rectangles like currently. I completely don't know how to do this. Buttons should look like these on the picture:
This isn't the prettiest way, but It will at least give you an Idea:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HexagonPattern extends JPanel {
private static final long serialVersionUID = 1L;
private static final int ROWS = 7;
private static final int COLUMNS = 7;
private HexagonButton[][] hexButton = new HexagonButton[ROWS][COLUMNS];
public HexagonPattern() {
setLayout(null);
initGUI();
}
public void initGUI() {
int offsetX = -10;
int offsetY = 0;
for(int row = 0; row < ROWS; row++) {
for(int col = 0; col < COLUMNS; col++){
hexButton[row][col] = new HexagonButton(row, col);
hexButton[row][col].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
HexagonButton clickedButton = (HexagonButton) e.getSource();
System.out.println("Button clicked: [" + clickedButton.getRow() + "][" + clickedButton.getCol() + "]");
}
});
add(hexButton[row][col]);
hexButton[row][col].setBounds(offsetY, offsetX, 105, 95);
offsetX += 87;
}
if(row%2 == 0) {
offsetX = -52;
} else {
offsetX = -10;
}
offsetY += 76;
}
}
public static void main(String[] args) {
HexagonPattern hexPattern = new HexagonPattern();
JFrame frame = new JFrame();
frame.setTitle("Hexagon Pattern");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(new Point(700, 300));
frame.add(hexPattern);
frame.setSize(550, 525);
frame.setResizable(false);
frame.setVisible(true);
}
//Following class draws the Buttons
class HexagonButton extends JButton {
private static final long serialVersionUID = 1L;
private static final int SIDES = 6;
private static final int SIDE_LENGTH = 50;
public static final int LENGTH = 95;
public static final int WIDTH = 105;
private int row = 0;
private int col = 0;
public HexagonButton(int row, int col) {
setContentAreaFilled(false);
setFocusPainted(true);
setBorderPainted(false);
setPreferredSize(new Dimension(WIDTH, LENGTH));
this.row = row;
this.col = col;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Polygon hex = new Polygon();
for (int i = 0; i < SIDES; i++) {
hex.addPoint((int) (50 + SIDE_LENGTH * Math.cos(i * 2 * Math.PI / SIDES)), //calculation for side
(int) (50 + SIDE_LENGTH * Math.sin(i * 2 * Math.PI / SIDES))); //calculation for side
}
g.drawPolygon(hex);
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
}
}
Test it out!
This program consists of 2 classes:
HexagonButton, which uses Graphics to draw a hexagon into a JButton. It also returns the row and column values when getRow or getCol are called.
HexagonPattern, which is the main class. It makes the pattern by laying them out with setBounds(x, y, width, height). It uses an ActionListener to print the coordinates of the Hexagon clicked, by calling getRow and getCol.
Like I said, this isn't the greatest program. If you want to make the hexagons smaller, then you'll have to change many variables.
I'm having an issue with a JPanel and I don't get what's going on. So I have a JFrame with a init function, that create a custom JPanel called GamePanel, and the strange thing is it never goes in the paintComponents function, even if I use repaint on the object.
Here is my code when I initialize the JPanel (in a JFrame):
this.gamePanel = new GamePanel(this.grid, this);
this.panel.add(this.gamePanel, constraints);
And the JPanel itself:
public class GamePanel extends JPanel {
private final int SQUARE_SIZE = 50;
private Grid grid;
private final GameView gameView;
public GamePanel(Grid grid, GameView gameView) {
this.gameView = gameView;
this.setPreferredSize(new Dimension(200, 200));
}
public void setGrid(Grid grid) {
this.grid = grid;
this.setPreferredSize(new Dimension(grid.getSizeX() * SQUARE_SIZE, grid.getSizeY() * SQUARE_SIZE));
}
#Override
public void paintComponents(Graphics g) {
System.out.println("test");
if (this.grid != null) {
Graphics2D g2 = (Graphics2D) g;
double thickness = 3;
g2.setStroke(new BasicStroke((float) thickness));
g2.setColor(Color.BLACK);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int x = SQUARE_SIZE * i;
int y = SQUARE_SIZE * j;
g2.drawRect(x, y, SQUARE_SIZE, SQUARE_SIZE);
if(this.grid.getSquareState(x, y) != 0) {
char[] tmp = ("" + this.grid.getSquareState(x, y)).toCharArray();
g2.drawChars(tmp, 0, 1, x, y);
}
}
}
}
}
}
EDIT: (the whole JFrame)
public class GameView extends JFrame {
private CustomSocket socket;
private JPanel panel;
private GamePanel gamePanel;
private JLabel listPlayers;
private JLabel playerPlaying;
private Grid grid;
public GameView(CustomSocket socket) {
this.socket = socket;
this.setTitle("TicTacToe - Client");
this.setSize(600, 480);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.init();
this.pack();
this.setVisible(true);
this.play();
}
private void init() {
this.panel = new JPanel();
this.panel.setLayout(new GridBagLayout());
GridBagConstraints constraints =new GridBagConstraints();
constraints.fill = GridBagConstraints.CENTER;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 1;
// Grid
this.gamePanel = new GamePanel(this.grid, this);
this.panel.add(this.gamePanel, constraints);
// Labels
constraints.gridy += 1;
this.listPlayers = new JLabel();
this.panel.add(this.listPlayers, constraints);
constraints.gridy += 1;
this.playerPlaying = new JLabel();
this.panel.add(this.playerPlaying, constraints);
this.setContentPane(this.panel);
}
private void play() {
String[] tmp = this.socket.getData().split(";");
this.grid = new Grid(Integer.parseInt(tmp[0]), Integer.parseInt(tmp[1]));
String players = "";
for(int i = 2; i < tmp.length; i++) {
players += tmp[i] + " ";
}
this.listPlayers.setText(players);
boolean notFinished = true;
while(notFinished) {
String[] gridData = this.socket.getData().split(";");
for(int i = 1; i < gridData.length; i++) {
String[] gridRow = gridData[i].replace("(", "").replace(")", "").split(",");
for(int j = 0; j < gridRow.length; j++) {
this.grid.setSquareState(i - 1, j, Integer.parseInt(gridRow[j]));
}
}
this.gamePanel.repaint();
String playerPlaying = this.socket.getData().split(";")[0];
if(playerPlaying != this.socket.getUsername()) {
}
notFinished = true;
}
}
}
Thank you in advance.
this.panel.add(this.gamePanel, constraints);
You add the component to a panel, but the panel doesn't have a preferred size. Since its size is (0, 0) there is nothing to paint so the method is never called.
All Swing components are responsible for determining their own preferred size. Override the getPreferredSize() method of your custom component. Then the layout manager can set the proper size/location of the component.
And paintComponent(...) is the proper method to override and don't forget the super.paintComponent(...) as the first statement to make sure the background gets cleared.
So I am in the process of creating a game similar to Plants vs Zombies, however I've run into a slight problem: before I can apply the finishing touches such as levels, I need to prevent more than one JLabel being added to a JPanel. The placing of the JLabel works fine, though I think that I may have gone a roundabout route. The problem as stated above is that another JLabel can currently be added below a pre-existing JLabel. How do I set a JPanel to accept no more than the original component (the initial JLabel)? Any assistance would be greatly appreciated.
private final JFrame FRAME;
private final JPanel squares[][] = new JPanel[8][11];
private final Color DGY = Color.DARK_GRAY;
private final Color GRN = Color.GREEN;
private final Color BLK = Color.BLACK;
private final Color LGY = Color.LIGHT_GRAY;
private final Color GRY = Color.GRAY;
private final Color BLU = Color.BLUE;
private final Font F1 = new Font("Tahoma", 1, 36);
private String icon = "";
private int lvl = 10;
private void squareGen(int i, int j, Color col, boolean border)
{
squares[i][j].setBackground(col);
if (border)
{
squares[i][j].setBorder(BorderFactory.createLineBorder(BLK, 1));
}
FRAME.add(squares[i][j]);
}
public GameGUI()
{
FRAME = new JFrame("ESKOM VS SA");
FRAME.setSize(1600, 900);
FRAME.setLayout(new GridLayout(8, 11));
for (int x = 0; x < 8; x++)
{
if (x > 1 && x < 7)
{
squares[x][0] = new JPanel();
squareGen(x, 0, GRN, true);
} else if (x == 1 || x == 7)
{
squares[x][0] = new JPanel();
squareGen(x, 0, DGY, true);
} else
{
squares[x][0] = new JPanel();
squareGen(x, 0, BLU, false);
}
for (int y = 1; y < 11; y++)
{
squares[x][y] = new JPanel();
if (x == 0)
{
squareGen(x, y, BLU, false);
} else if (y == 10 || x == 1 || x == 7)
{
squareGen(x, y, DGY, true);
} else
{
squareGen(x, y, LGY, true);
addDToPanel(x, y);
}
}
}
JButton btnPause = new JButton();
btnPause.setText("||");
btnPause.setFont(F1);
btnPause.addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnPauseActionPerformed(evt);
}
});
squares[7][10].add(btnPause);
addButtons(8);
FRAME.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
FRAME.setLocationRelativeTo(null);
}
public void restart()
{
FRAME.dispose();
GameGUI ggui = new GameGUI();
ggui.setVisible(true);
}
public void mainMenu()
{
FRAME.dispose();
new StartUpUI().setVisible(true);
}
private void btnPauseActionPerformed(java.awt.event.ActionEvent evt)
{
new PauseGUI(this).setVisible(true);
}
private void btnAddDefenseActionPerformed(java.awt.event.ActionEvent evt)
{
JButton btn = (JButton) evt.getSource();
icon = btn.getActionCommand();
}
private void addButtons(int x)
{
JButton[] btn = new JButton[x];
for (int j = 1; j <= x; j++)
{
btn[j - 1] = new JButton();
ImageIcon ii = new ImageIcon(this.getClass().getResource("" + j + ".png"));
btn[j - 1].setIcon(ii);
btn[j - 1].setActionCommand("" + j);
btn[j - 1].setText("");
btn[j - 1].setForeground(btn[j - 1].getBackground());
squares[0][j].add(btn[j - 1]);
btn[j - 1].addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnAddDefenseActionPerformed(evt);
}
});
}
}
private void addDToPanel(int x, int y)
{
squares[x][y].addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent me)
{
JPanel panel = (JPanel) me.getSource();
int j = (int) (panel.getX() / 145.45454545) + 1;
int i = (int) (panel.getY() / 112.5) + 1;
addDefense(i, j, icon);
icon = "";
FRAME.revalidate();
FRAME.repaint();
}
});
}
private void addDefense(int i, int j, String imageName)
{
try
{
JLabel jlbl = new JLabel();
ImageIcon ii = new ImageIcon(this.getClass().getResource(imageName + ".png"));
jlbl.setIcon(ii);
squares[i][j].add(jlbl, java.awt.BorderLayout.CENTER);
} catch (Exception e)
{
}
}
public void setLvl(int lvl)
{
this.lvl = lvl;
}
public void setVisible(boolean b)
{
FRAME.setVisible(b);
}
This is not my main class, this class is instantiated in the main class and setVisible() = true;
Again thanks in advance!
How do I set a JPanel to accept no more than the original
You can use the Container.getComponentCount() method to check how many components have been added to the panel.
Only add your component when the count is 0.
I'm struggling with this code, I want to click on one of the cells of the grid, made by JPanel objects, and in that cell make appear a label with the index of that cell. I made a method to add final vars and return the JPanel with that label. It's not working. How can I do this?
public MyTest01(int width, int length) { //constructor
frame.setLayout(new GridLayout(width, length)); //set layout
JPanel temp = null;
JLabel l;
for (int y = 0; y < length; y++) {
for (int x = 0; x < width; x++) {
temp = new JPanel();
temp.setBorder(new LineBorder(Color.black, 1));
temp=doStuff(temp,x,y);
frame.add(temp);
}
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack(); //sets appropriate size for frame
frame.setVisible(true); //makes frame visible
}
public static JPanel doStuff( final JPanel temp,final int x, final int y) {
MouseListener mouseListener = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent mouseEvent) {
JLabel l = new JLabel("("+x+" - "+y+")");
temp.add(l);
}
};
return temp;
}
You never add the listener to the JPanel.
You need to revalidate and repaint the JPanel after adding a component (JLabel);
MouseListener mouseListener = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent mouseEvent) {
JLabel l = new JLabel("(" + x + " - " + y + ")");
temp.add(l);
temp.revalidate();; <-------- revalidate
temp.repaint(); <-------- repaint
}
};
temp.addMouseListener(mouseListener); <-------- add listener
return temp;
Here is the working code
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class MyTest {
JFrame frame = new JFrame();
public MyTest(int width, int length) { //constructor
frame.setLayout(new GridLayout(width, length)); //set layout
JPanel temp = null;
JLabel l;
for (int y = 0; y < length; y++) {
for (int x = 0; x < width; x++) {
temp = new JPanel();
temp.setBorder(new LineBorder(Color.black, 1));
temp = doStuff(temp, x, y);
frame.add(temp);
}
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack(); //sets appropriate size for frame
frame.setVisible(true); //makes frame visible
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MyTest(3, 3);
}
});
}
public static JPanel doStuff(final JPanel temp, final int x, final int y) {
MouseListener mouseListener = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent mouseEvent) {
JLabel l = new JLabel("(" + x + " - " + y + ")");
temp.add(l);
temp.revalidate();;
temp.repaint();
}
};
temp.addMouseListener(mouseListener);
return temp;
}
}
I am designing a grid-based game which uses the Java swing framework. I have a JFrame with two JPanel within it, but one of them appears in two places. Here is a screenshot:
The panel that says "Turn 1" and has the buttons is only supposed to appear to the right of the grid, but it strangely also appears in the upper-left hand corner. Here is my code:
public class ArenaPanel extends JPanel {
private final GridPanel gp;
private final InfoPanel ip;
private GameManager gm;
private int w, h;
private int cw, ch;
private double tw, th;
private Point p2;
private Point p1;
private int shotWidth;
private Color shotColor;
public ArenaPanel(int w, int h) {
Images.load();
setLayout(new GridBagLayout());
this.w = w;
this.h = h;
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 1;
c.weightx = 0;
c.weighty = 1;
gp = new GridPanel();
gp.setPreferredSize(new Dimension(700, 700));
this.add(gp, c);
c.gridx = 1;
c.weightx = c.weighty = 0;
ip = new InfoPanel();
add(ip, c);
}
public void setGameManager(GameManager g) {
gm = g;
}
public void start() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
gm.start();
}
});
t.start();
}
public void step() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
gm.doTurn();
}
});
t.start();
}
public void paint(Graphics g) {
g.setColor(Color.black);
int val = Math.min(getWidth() - 200, getHeight());
gp.setPreferredSize(new Dimension(val, val));
gp.revalidate();
g.fillRect(0, 0, getWidth(), getHeight());
paintComponents(g);
}
private class GridPanel extends JPanel {
public void paint(Graphics g) {
cw = getWidth();
ch = getHeight();
g.setColor(Color.gray);
g.fillRect(0, 0, cw, ch);
tw = (double) cw / w;
th = (double) ch / h;
g.setColor(Color.black);
for (int i = 0; i < w; i++) {
g.drawLine((int) (i * tw), 0, (int) (i * tw), ch);
}
for (int i = 0; i < h; i++) {
g.drawLine(0, (int) (i * th), cw, (int) (i * th));
}
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
Robot t = gm.getGrid()[i][j];
if (t != null) {
Point p = expand(i, j);
g.drawImage(t.getImage(), p.x + t.getOffsetX(),
p.y + t.getOffsetY(), (int) tw, (int) th, null);
}
}
}
if (p1 != null) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(shotColor);
g2.setStroke(new BasicStroke(shotWidth));
g2.drawLine(p1.x, p1.y, p2.x, p2.y);
p1 = null;
p2 = null;
}
}
}
private class InfoPanel extends JPanel implements ActionListener {
private JButton start, stop, step;
private JLabel turns;
private int numTurns = 0;
private GridBagConstraints gbc;
private ArrayList<TeamPanel> tpanels;
public InfoPanel() {
JPanel buttons = new JPanel();
setLayout(new GridBagLayout());
buttons.setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
start = new JButton("Start");
gbc.gridy = 0;
gbc.gridx = 1;
turns = new JLabel("Turn 1");
buttons.add(turns, gbc);
start.addActionListener(this);
gbc.gridy = 1;
gbc.gridx = 0;
buttons.add(start, gbc);
step = new JButton("Step");
step.addActionListener(this);
gbc.gridx++;
buttons.add(step, gbc);
stop = new JButton("Stop");
stop.addActionListener(this);
gbc.gridx++;
buttons.add(stop, gbc);
gbc.gridx = 0;
gbc.gridy = 0;
add(buttons, gbc);
tpanels = new ArrayList<TeamPanel>();
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == start) {
start();
} else if (actionEvent.getSource() == stop) {
gm.stop();
} else if (actionEvent.getSource() == step) {
step();
}
}
public void incrementTurn() {
numTurns++;
turns.setText("Turn " + numTurns);
}
public void initializeTeams(Map<String, TeamInfo> m) {
Set<String> k = m.keySet();
for (TeamPanel tp : tpanels) {
this.remove(tp);
}
tpanels.clear();
gbc.gridy = 1;
for (String s : k) {
TeamPanel tp = new TeamPanel(m.get(s));
add(tp, gbc);
gbc.gridy++;
tpanels.add(tp);
}
this.revalidate();
}
}
private class TeamPanel extends JPanel {
private Color col;
private int score;
private JLabel scoreLabel;
private TeamInfo inf;
public TeamPanel(TeamInfo inf) {
this.inf = inf;
col = getColor(inf.c);
super.setLayout(new FlowLayout());
BufferedImage ico = new BufferedImage(20, 20, BufferedImage.TYPE_3BYTE_BGR);
Graphics g = ico.getGraphics();
g.setColor(col);
g.fillRect(0, 0, 20, 20);
add(new JLabel(new ImageIcon(ico)));
this.add(new JLabel(inf.team));
scoreLabel = new JLabel("" + inf.score);
add(scoreLabel);
}
public void paint(Graphics g) {
//g.setColor(col);
//g.fillRect(-5, 0, 10, 10);
scoreLabel.setText("Score: " + inf.score);
this.paintComponents(g);
}
}
public void initializeTeams(Map<String, TeamInfo> m) {
ip.initializeTeams(m);
}
}
I have looked on google and StackOverflow for a similar problem, but I was unable to find one. Any help would be greatly appreciated.
Thanks!
Don't override the paint(...) method
Override the JPanel's paintComponent(...) method instead.
Don't forget to call the super paintComponent(...) method within your override.
And never call the super's paintComponents(...) (note the trailing "s") from within either the paint or paintComponent method. This smells like it could be the cause of your problem.