As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I want to add, move and set properties (font and rotation) of components at runtime.
In other words, I need to add a button, a label, drag them using mouse and set a component's properties at runtime. Is there any example Java swing for or similar to this?
This is my code :
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.io.File;
import java.sql.SQLException;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class prova extends JFrame implements MouseMotionListener,MouseListener{
//*************** INIZIALIZZAZIONE VARIABILI ***************************
Checkbox CB=new Checkbox("Label",true);
Button BP=new Button("BUTTON_1");
Button B=new Button("OK");
JComboBox combo1=new JComboBox();
JMenuBar menuBar;
int app=0;
static int anglePeso=0;
static int angleTara=0;
ImageIcon ic;
Border border = LineBorder.createBlackLineBorder();
static int pesoX=184;
static int pesoY=91;
static boolean taraVisible=false;
static boolean pesoVisible=false;
static boolean logo1Visible=false;
static boolean BarCodeVisible=false;
static String font="";
static String rot="";
Label societa=new Label ("Società");
Label importo=new Label ("Importo");
Label nome=new Label("Nome Prodotto");
static int logo1X=250;
static int logo1Y=90;
static Component C;
static int label1X=183;
static int label1Y=91;
static int taraX=100;
//TextField TF=new TextField(10);
static Panel P=new Panel();
//List TA=new List();
boolean b1=false;
int c1=0;int c2=0;
static JLabel logo2=new JLabel("Logo2");
static int aa=0;
static int importoX=0;
static int importoY=0;
public static boolean isBarCodeVisible() {
return BarCodeVisible;
}
public static void setBarCodeVisible(boolean BarCodeVisible) {
prova.BarCodeVisible = BarCodeVisible;
}
public static Component getC() {
return C;
}
public static void setC(Component C) {
prova.C = C;
}
public static int getAnglePeso() {
return anglePeso;
}
public static void setAnglePeso(int anglePeso) {
prova.anglePeso = anglePeso;
}
static ImageIcon immLogo1;
public JLabel getBarcode() {
return barcode;
}
public void setBarcode(JLabel barcode) {
this.barcode = barcode;
}
public static ImageIcon getImmLogo1() {
return immLogo1;
}
public static void setImmLogo1(ImageIcon immLogo1) {
prova.immLogo1 = immLogo1;
}
public static void setFont(String font) {
prova.font = font;
}
public static String getRot() {
return rot;
}
public static void setRot(String rot) {
prova.rot = rot;
}
public static boolean isPesoVisible() {
return pesoVisible;
}
public static void setPesoVisible(boolean pesoVisible) {
prova.pesoVisible = pesoVisible;
}
public static boolean isTaraVisible() {
return taraVisible;
}
public static void setTaraVisible(boolean taraVisible) {
prova.taraVisible = taraVisible;
}
static JLabel label1=new JLabel("Peso"){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
double x = getWidth()/2.0;
double y = getHeight()/2.0;
aT.rotate(Math.toRadians(anglePeso), x, y);
// g2.transform(aT);
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
Label data=new Label("Data");
static JLabel tara=new JLabel("Tara"){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
double x = getWidth()/2.0;
double y = getHeight()/2.0;
aT.rotate(Math.toRadians(angleTara), x, y);
// g2.transform(aT);
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
static JLabel logo1=new JLabel("Logo1");
public static JLabel getTara() {
return tara;
}
public static void setTara(JLabel tara) {
prova.tara = tara;
}
static JLabel barcode=new JLabel ("Bar Code");/*{
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
double x = getWidth()/2.0;
double y = getHeight()/2.0;
aT.rotate(Math.toRadians(angle), x, y);
// g2.transform(aT);
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
*/
public static JLabel getLogo1() {
return logo1;
}
public static void setLogo1(JLabel logo1) {
prova.logo1 = logo1;
}
public static boolean isLogo1Visible() {
return logo1Visible;
}
public static void setLogo1Visible(boolean logo1Visible) {
prova.logo1Visible = logo1Visible;
}
public static int getLogo1X() {
return logo1X;
}
public static void setLogo1X(int logo1X) {
prova.logo1X = logo1X;
}
public static int getLogo1Y() {
return logo1Y;
}
public static void setLogo1Y(int logo1Y) {
prova.logo1Y = logo1Y;
}
public static int getTaraX() {
return taraX;
}
public static void setTaraX(int taraX) {
prova.taraX = taraX;
}
public static int getTaraY() {
return taraY;
}
public static void setTaraY(int taraY) {
prova.taraY = taraY;
}
static int taraY=90;
public int getLabel1X() {
return label1X;
}
public void setLabel1X(int label1X) {
this.label1X = label1X;
}
public int getLabel1Y() {
return label1Y;
}
public void setLabel1Y(int label1Y) {
this.label1Y = label1Y;
}
public prova(){
}
public prova(String titlu)
{
super(titlu);
}
void init(int b,int h, String [] par) throws ClassNotFoundException, SQLException
{
setLayout(null);
System.out.println("****************COORINATE PESO: "+label1X+" "+label1Y);
menuBar = new JMenuBar();
JMenuBar menubar = new JMenuBar();
JMenu filemenu = new JMenu("File");
filemenu.add(new JSeparator());
JMenu editmenu = new JMenu("Edit");
editmenu.add(new JSeparator());
JMenuItem fileItem1 = new JMenuItem("New");
JMenuItem fileItem2 = new JMenuItem("Open");
JMenuItem fileItem3 = new JMenuItem("Close");
fileItem3.add(new JSeparator());
JMenuItem fileItem4 = new JMenuItem("Save");
JMenuItem editItem1 = new JMenuItem("Cut");
JMenuItem editItem2 = new JMenuItem("Copy");
editItem2.add(new JSeparator());
JMenuItem editItem3 = new JMenuItem("Paste");
JMenuItem editItem4 = new JMenuItem("Insert");
filemenu.add(fileItem1);
filemenu.add(fileItem2);
filemenu.add(fileItem3);
filemenu.add(fileItem4);
editmenu.add(editItem1);
editmenu.add(editItem2);
editmenu.add(editItem3);
editmenu.add(editItem4);
menubar.add(filemenu);
menubar.add(editmenu);
setJMenuBar(menubar);
//setSize(400,400);
//setVisible(true);
fileItem4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println("Cliccato Save ");
punti();
setVisible(false);
}
});
InserimentoDB is=new InserimentoDB();
Image im=is.getImage("select immagine from etichette where id= 75");
ic=new ImageIcon(im);
P.setBackground(Color.red);
String[] mm=new String [4];
mm[0]="0";
mm[1]="90";
mm[2]="180";
mm[3]="270";
combo1.setModel(new DefaultComboBoxModel(mm) {});
combo1.addMouseMotionListener(this);
combo1.addMouseListener(this);
combo1.setLocation(200,100);combo1.setSize(80,40);
//add(combo1);
System.out.println("LabelX: "+label1X);
System.out.println("LabelY: "+label1Y);
// label1.getParent().repaint();
/*
l.addMouseMotionListener(this);
l.addMouseListener(this);
l1.addMouseMotionListener(this);
l1.addMouseListener(this);
l2.addMouseMotionListener(this);
l2.addMouseListener(this);
l3.addMouseMotionListener(this);
l3.addMouseListener(this);
*/
for (int i=0; i<par.length; i++){
System.out.println("Parametri ricevuti "+par[i]);
}
//TA.addMouseMotionListener(this);
//TA.addMouseListener(this);
B.addMouseMotionListener(this);
B.addMouseListener(this);
P.addMouseMotionListener(this);
P.addMouseListener(this);
CB.addMouseMotionListener(this);
CB.addMouseListener(this);
if (par[6].equalsIgnoreCase("logo1")){
if(logo1Visible){
System.out.println("*******LOGO1: "+immLogo1);
// logo1.setIcon(immLogo1);
logo1.addMouseMotionListener(this);
logo1.addMouseListener(this);
// System.out.println("Imm Logo1: "+immLogo1.getDescription());
logo1.setIcon(ic);
logo1.setLocation(logo1X,logo1Y);
//label1.setLocation(pesoX,pesoY);
logo1.setSize(384,160);
add(logo1);
}
}
if (par[0].equalsIgnoreCase("peso")){
if(pesoVisible){
// label1.setBorder(border);
label1.addMouseMotionListener(this);
label1.addMouseListener(this);
label1.setBorder(BorderFactory.createEtchedBorder());
//label1.setFont(font);
label1.setLocation(label1X,label1Y);
//label1.setLocation(pesoX,pesoY);
label1.setSize(100,20);
// label1.setIcon(immLogo1);
add(getContent());
//add(getCombo());
label1.setName("peso");
add(label1);
repaint();
}
}
if (par[1].equalsIgnoreCase("tara")){
if(taraVisible){
tara.addMouseMotionListener(this);
tara.addMouseListener(this);
//tara.setLocation(49,130);
tara.setBorder(BorderFactory.createEtchedBorder());
tara.setLocation(taraX,taraY);
tara.setSize(100,20);
tara.setName("tara");
add(tara);
repaint();
}
}
if (par[2].equalsIgnoreCase("importo")){
importo.addMouseMotionListener(this);
importo.addMouseListener(this);
importo.setLocation(44,91);importo.setSize(100,20);
importo.setName("IMPORTO");
add(importo);
}
if (par[3].equalsIgnoreCase("bar code")){
if(BarCodeVisible){
barcode.addMouseMotionListener(this);
barcode.addMouseListener(this);
ImageIcon icon = new ImageIcon("/home/max/Downloads/ce.jpg");
barcode.setIcon(icon);
barcode.setLocation(81,223);barcode.setSize(284,177);
add(barcode);
}
}
if (par[4].equalsIgnoreCase("data")){
data.addMouseMotionListener(this);
data.addMouseListener(this);
// data.setLocation(184,177);
data.setSize(100,20);
data.setName("data");
add(data);
}
if (par[5].equalsIgnoreCase("nome prodotto")){
nome.addMouseMotionListener(this);
nome.addMouseListener(this);
nome.setLocation(43,186);nome.setSize(100,20);
add(nome);
}
ImageIcon icon1 = new ImageIcon("/home/max/Downloads/ce.jpg");
logo2.setIcon(icon1);
logo2.setLocation(100, 50);
add(logo2);
//add(B);***********************
B.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
System.out.println("Cliccato");
punti();
setVisible(false);
}
});
/*data.addMouseMotionListener(this);
data.addMouseListener(this);
societa.addMouseMotionListener(this);
societa.addMouseListener(this);
barcode.addMouseMotionListener(this);
barcode.addMouseListener(this);
TA.setLocation(50,50);
TA.setSize(100,100);TA.add("List");
CB.setLocation(120,370);CB.setSize(100,20);
data.setLocation(184,177);data.setSize(100,20);
societa.setLocation(112,41);societa.setSize(100,20);
barcode.setLocation(44,178);barcode.setSize(100,20);*/
B.setLocation(100,150);B.setSize(80,40);
P.setLayout(new BorderLayout());
P.setLocation(100,200);P.setSize(150,150);
P.setBackground(Color.yellow);
P.add(BP,BorderLayout.NORTH);
//P.add(TF,BorderLayout.SOUTH);
//add(TA);add(B);add(P);add(CB);
//add(l);add(l1);add(l2);add(l3);add(label);
//add(label);
//add(data);add(societa);add(tara);add(barcode);
setLocation(500,500);
setSize(b*10,h*10);
setVisible(true);
//show();
}
//mouseDragged
public void mouseDragged(MouseEvent e)
{
Component C=e.getComponent();
if(b1==false){b1=true;Point p=new
Point(e.getPoint());c1=p.x;c2=p.y;}
Point z=new Point(e.getPoint());
Point q=new Point(C.getLocation());
C.setBounds(q.x+(z.x-c1),q.y+(z.y-c2),C.getSize().
width,C.getSize().height);
repaint();
}
//mouseReleased
public void mouseReleased(MouseEvent e)
{
b1=false;
System.out.println("Mouse Rilascaito");
Component C=e.getComponent();
System.out.println("*******++++++++++**********+++++++++Coordinate"+ C);
System.out.println("NOme: "+C.getName());
if(C.getName().equalsIgnoreCase("importo")){
importo.setLocation(C.getX(), C.getY());
importoX=C.getX();
importoY=C.getY();
}
if(C.getName().equalsIgnoreCase("data")){
data.setLocation(C.getX(), C.getY());
}
if(C.getName().equalsIgnoreCase("peso")){
label1X=C.getX();
label1Y=C.getY();
}
C.getX();
C.getY();
//Attenzione qui sotto da controllare!!!!!!!
//pesoX=e.getX();
//pesoY=e.getY();
repaint();
}
//mouseEntered
public void mouseEntered(MouseEvent e)
{
Cursor c1=new Cursor(Cursor.HAND_CURSOR);
setCursor(c1);
}
//mouseExited
public void mouseExited(MouseEvent e)
{
Cursor c2=new Cursor(Cursor.DEFAULT_CURSOR);
setCursor(c2);
}
//mouseClicked
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2) {
Component C=e.getComponent();
System.out.println("*****************+NOme componente: "+C.getName());
System.out.println("Coordinate: "+C.getLocation());
System.out.println("XXX: "+C.getX());
System.out.println("YYY: "+C.getY());
// Configurazione cc=new Configurazione();
// cc.setComponente(C.getName());
// cc.main();
Configurazione cf=new Configurazione();
// cf.setC(C);
cf.main();
//RotLabel rot=new RotLabel();
//rot.main();
System.out.println("\n\nRotazione: "+rot);
System.out.println("Font: "+font);
System.out.println("\n\n");
System.out.println("+++++++++++++++++++++++++++++++Clicccato 2 volte");
/* JFrame frame=new JFrame("Configurazione");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocation(200, 300);
JLabel titolo=new JLabel("Configurazione "+C.getName());
JLabel rotazione=new JLabel("Rotazione");
String [] val=new String [4];
val[0]="0";
val[1]="90";
val[2]="180";
val[3]="270";
JComboBox scelta=new JComboBox(val);
frame.add(titolo);
frame.add(rotazione);
frame.add(scelta);
//3. Create components and put them in the frame.
//...create emptyLabel...
//frame.getContentPane().add(new JLabel("Configurazione"), BorderLayout.CENTER);
//4. Size the frame.
frame.pack();
//5. Show it.
frame.setVisible(true);*/
}
Component C=e.getComponent();
C.getParent().repaint();
repaint();
System.out.println("Coordinate"+ C);
}
//mouseMoved
public void mouseMoved(MouseEvent e)
{
Component C=((Component)e.getSource());
java.util.Random r=new java.util.Random();
java.util.Random g=new java.util.Random();
java.util.Random b=new java.util.Random();
int cr=r.nextInt(255);int cg=g.nextInt(255);
int cb=b.nextInt(255);
Color col=new Color(cr,cg,cb);
//C.setBackground(col);
}
//mousePressed
public void mousePressed(MouseEvent e){}
public class mouse_events{}
public static void punti(){
Inizio in=new Inizio();
System.out.println("\n\n****************Controllo visibilità: ");
System.out.println("Peso: "+pesoVisible);
System.out.println("Tara: "+taraVisible);
System.out.println("Logo1: "+logo1Visible);
System.out.println("***********************************\n\n");
if(logo1Visible){
System.out.println("Parametri Logo1 "+logo1.getLocation());
System.out.println("Parametri X Logo1 "+logo1.getX());
in.setLogo1X(logo1.getX());
//System.out.println("Scrivo app: "+app);
System.out.println("Parametri Y Logo1 "+logo1.getY());
in.setLogo1Y(logo1.getY());
}
if(pesoVisible){
System.out.println("Parametri Label "+label1.getLocation());
System.out.println("Parametri X Label "+label1.getX());
in.setLabelX(label1.getX());
//System.out.println("Scrivo app: "+app);
System.out.println("Parametri Y Label "+label1.getY());
in.setLabelY(label1.getY());
}
if(taraVisible){
System.out.println("Parametri tara "+tara.getLocation());
System.out.println("Parametri X Tara "+tara.getX());
in.setTaraX(tara.getX());
//System.out.println("Scrivo app: "+app);
System.out.println("Parametri Y Tara "+tara.getY());
in.setTaraY(tara.getY());
}
System.out.println("Parametri Bar Code "+barcode.getLocation());
System.out.println("Parametri X Bar code "+barcode.getX()/10);
in.setBarX(barcode.getX()/10);
//System.out.println("Scrivo app: "+app);
System.out.println("Parametri Y Bar Code "+barcode.getY()/10);
in.setBarY(barcode.getY()/10);
// System.out.println("Parametri nome "+nome.getLocation());
// System.out.println("Parametri X nome "+nome.getX()/10);
// in.setNomeX(nome.getX()/10);
//System.out.println("Scrivo app: "+app);
// System.out.println("Parametri Y nome "+nome.getY()/10);
// in.setNomeY(nome.getY()/10);
// System.out.println("Parametri importo "+importo.getLocation());
// System.out.println("Parametri X importo "+importo.getX()/10);
// in.setImportoX(importo.getX()/10);
//System.out.println("Scrivo app: "+app);
// System.out.println("Parametri Y importo "+importo.getY()/10);
// in.setImportoY(importo.getY()/10);
// System.out.println("Parametri data "+data.getLocation());
// System.out.println("Parametri X data"+data.getX()/10);
// in.setDataX(data.getX()/10);
//aa=data.getX();
//System.out.println("Scrivo app: "+app);
// System.out.println("Parametri Y data "+data.getY()/10);
// in.setDataY(data.getY()/10);
}
public void visibile(boolean vis){
P.setVisible(vis);
/*
WindowEvent close = new WindowEvent(FRAME, WindowEvent.WINDOW_CLOSING);
FRAME.dispatchEvent(close);
*/
}
/*
private JComboBox getCombo(){
//final JSlider slider = new JSlider(-180, 180, angle);
String[] val=new String [4];
val[0]="0";
val[1]="90";
val[2]="180";
val[3]="270";
//final JComboBox combo1=new JComboBox(val);
combo1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// angle = Integer.parseInt(combo1.getSelectedItem().toString());//.getValue();
label1.getParent().repaint();
}
});
return combo1;
}*/
private JPanel getContent() {
label1.setFont(new Font("Monospaced", Font.PLAIN, 24));
label1.setBorder(BorderFactory.createEtchedBorder());
JPanel panel = new JPanel(new GridBagLayout());
panel.add(label1, new GridBagConstraints());
return panel;
}
/*
public static void main(String[] args)
{
prova t=new prova("MOUSE EVENT");
t.init();
}*/
public static void refresh(){
//P.getParent().repaint();
P.repaint();
//add(label1);
//repaint();
}
}
Thanks.
Years ago I wrote a framework for this. Maybe it can serve you as a start (the library is Open Source):
Tutorial: http://softsmithy.sourceforge.net/lib/current/docs/tutorial/swing/customizer/index.html
Javadoc: http://softsmithy.sourceforge.net/lib/current/docs/api/softsmithy-lib-core/index.html
Homepage: http://softsmithy.sourceforge.net/
Maven:
<dependency>
<groupId>org.softsmithy.lib</groupId>
<artifactId>softsmithy-lib-core</artifactId>
<version>0.2</version>
</dependency>
More info: http://puces-blog.blogspot.ch/2012/07/news-from-software-smithy-version-02.html
Other solutions:
You could consider the NetBeans Platform and try to reuse either its Matisse component or the Visual Graph library.
Related
I'm trying to create a "Tic Tac Toe" game. I've chosen to create a variation of JPanel to represent each square. The class beneath represents one of 9 panels that together make up my game board.
Now the problem I'm having is that when I click the panel a 'X' should be displayed inside of the panel, but nothing happens. I'd very much appreciate it if someone steered me in the right direction.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TicTacToePanel extends JPanel implements MouseListener {
private boolean isPlayer1Turn = true;
private boolean isUsed = false;
private JLabel ticTacLbl = new JLabel();
public TicTacToePanel() {
setBorder(BorderFactory.createLineBorder(Color.BLACK));
addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
if (!isUsed) {
if (isPlayer1Turn) {
ticTacLbl.setForeground(Color.red);
ticTacLbl.setText("X");
add(ticTacLbl, 0);
isUsed = true;
} else {
ticTacLbl.setForeground(Color.blue);
ticTacLbl.setText("O");
add(ticTacLbl, 0);
isUsed = true;
}
} else {
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, new TicTacToePanel());
}
}
EDIT:
I simply added my label component in the constructor of my TicTacToePanel so that I no longer have to call revalidate() and I'm not adding components during runtime.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TicTacToePanel extends JPanel implements MouseListener{
private boolean isPlayer1Turn = true;
private boolean isUsed = false;
private JLabel ticTacLbl = new JLabel();
public TicTacToePanel(){
add(ticTacLbl, 0);
setBorder(BorderFactory.createLineBorder(Color.BLACK));
addMouseListener(this);
}
public void mouseClicked(MouseEvent e){
}
public void mousePressed(MouseEvent e){
if (!isUsed) {
if (isPlayer1Turn) {
ticTacLbl.setForeground(Color.red);
ticTacLbl.setText("X");
isUsed = true;
} else {
ticTacLbl.setForeground(Color.blue);
ticTacLbl.setText("O");
isUsed = true;
}
}
else{
}
}
public void mouseReleased(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public static void main(String[] args){
JOptionPane.showMessageDialog(null, new TicTacToePanel());
}
}
The GUI constructor:
public TicTacToeGUI(int gameMode){
if(gameMode == 0){
amountOfPanels = 9;
TicTacToePanel[] panelArr = new TicTacToePanel[amountOfPanels];
add(gamePanel, new GridLayout(3, 3));
setPreferredSize(new Dimension(100, 100));
for(int i = 0; i < amountOfPanels; i++){
panelArr[i] = new TicTacToePanel();
gamePanel.add(panelArr[i]);
}
}
else if(gameMode == 1){
amountOfPanels = 225;
TicTacToePanel[] panelArr = new TicTacToePanel[amountOfPanels];
add(gamePanel, new GridLayout(15, 15));
setPreferredSize(new Dimension(500, 500));
for(int i = 0; i < amountOfPanels; i++){
panelArr[i] = new TicTacToePanel();
gamePanel.add(panelArr[i]);
}
}
}
public static void main(String[] args){
JOptionPane.showMessageDialog(null, new TicTacToeGUI(0));
}
}
When you add/remove components at runtime, always call revalidate() afterwards. revalidate() makes the component refresh/relayout.
So just call revalidate() after you add the label and it will work.
If you're goal is to create a Tic Tac Toe game, then you may wish to re-think your current strategy of adding components to the GUI on the fly. Much better would be to create a grid of components, say of JLabel, and place them on the JPanel at program start up. This way you can change the pressed JLabel's text and color, and even its Icon if you want to be fancy during program run without having to add or remove components. For example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
#SuppressWarnings("serial")
public class TicTacToePanel extends JPanel {
private static final int ROWS = 3;
private static final int MY_C = 240;
private static final Color BG = new Color(MY_C, MY_C, MY_C);
private static final int PTS = 60;
private static final Font FONT = new Font(Font.SANS_SERIF, Font.BOLD, PTS);
public static final Color X_COLOR = Color.BLUE;
public static final Color O_COLOR = Color.RED;
private JLabel[][] labels = new JLabel[ROWS][ROWS];
private boolean xTurn = true;
public TicTacToePanel() {
setLayout(new GridLayout(ROWS, ROWS, 2, 2));
setBackground(Color.black);
MyMouse myMouse = new MyMouse();
for (int row = 0; row < labels.length; row++) {
for (int col = 0; col < labels[row].length; col++) {
JLabel label = new JLabel(" ", SwingConstants.CENTER);
label.setOpaque(true);
label.setBackground(BG);
label.setFont(FONT);
add(label);
label.addMouseListener(myMouse);
}
}
}
private class MyMouse extends MouseAdapter {
#Override // override mousePressed not mouseClicked
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
String text = label.getText().trim();
if (!text.isEmpty()) {
return;
}
if (xTurn) {
label.setForeground(X_COLOR);
label.setText("X");
} else {
label.setForeground(O_COLOR);
label.setText("O");
}
// information to help check for win
int chosenX = -1;
int chosenY = -1;
for (int x = 0; x < labels.length; x++) {
for (int y = 0; y < labels[x].length; y++) {
if (labels[x][y] == label) {
chosenX = x;
chosenY = y;
}
}
}
// TODO: check for win here
xTurn = !xTurn;
}
}
private static void createAndShowGui() {
TicTacToePanel mainPanel = new TicTacToePanel();
JFrame frame = new JFrame("Tic Tac Toe");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Here is my code. I want to know which l was clicked and then in a new frame, display that ImageIcon.
The e.getSource() is not working...
final JFrame shirts = new JFrame("T-shirts");
JPanel panel = new JPanel(new GridLayout(4, 4, 3, 3));
for (int i = 1; i < 13; i++) {
l = new JLabel(new ImageIcon("T-shirts/"+i+".jpg"), JLabel.CENTER);
l.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
l.setFont(l.getFont().deriveFont(20f));
panel.add(l);
}//end of for loop
panel.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e)
{
sizes = new JFrame("Shopping");
sizes.setVisible(true);
sizes.setSize(500, 500);
sizes.setLocation(100,200);
shirts.dispose();
if(e.getSource()==l){//FIX
sizes.add(l);
}//end of if
}
});
shirts.setContentPane(panel);
shirts.setSize(1000, 1000);
shirts.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
shirts.setVisible(true);
If you add your MouseListener directly to your JLabels, then you can display the pressed label's icon easily in a JOptionPane:
#Override
public void mousePressed(MouseEvent mEvt) {
JLabel label = (JLabel) mEvt.getSource();
Icon icon = label.getIcon();
JOptionPane.showMessageDialog(label, icon);
}
For example:
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
public class FooMouseListener extends JPanel {
private GetImages getImages;
public FooMouseListener() throws IOException {
getImages = new GetImages();
setLayout(new GridLayout(GetImages.SPRITE_ROWS, GetImages.SPRITE_COLS));
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
for (int i = 0; i < GetImages.SPRITE_CELLS; i++) {
JLabel label = new JLabel(getImages.getIcon(i));
add(label);
label.addMouseListener(myMouseAdapter);
}
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
Icon icon = label.getIcon();
JOptionPane.showMessageDialog(label, icon, "Selected Icon", JOptionPane.PLAIN_MESSAGE);
}
}
private static void createAndShowGui() {
FooMouseListener mainPanel = null;
try {
mainPanel = new FooMouseListener();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("FooMouseListener");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class GetImages {
private static final String SPRITE_PATH = "http://th02.deviantart.net/"
+ "fs70/PRE/i/2011/169/0/8/blue_player_sprite_sheet_by_resetado-d3j7zba.png";
public static final int SPRITE_ROWS = 6;
public static final int SPRITE_COLS = 6;
public static final int SPRITE_CELLS = SPRITE_COLS * SPRITE_ROWS;
private List<Icon> iconList = new ArrayList<>();
public GetImages() throws IOException {
URL imgUrl = new URL(SPRITE_PATH);
BufferedImage mainImage = ImageIO.read(imgUrl);
for (int i = 0; i < SPRITE_CELLS; i++) {
int row = i / SPRITE_COLS;
int col = i % SPRITE_COLS;
int x = (int) (((double) mainImage.getWidth() * col) / SPRITE_COLS);
int y = (int) ((double) (mainImage.getHeight() * row) / SPRITE_ROWS);
int w = (int) ((double) mainImage.getWidth() / SPRITE_COLS);
int h = (int) ((double) mainImage.getHeight() / SPRITE_ROWS);
BufferedImage img = mainImage.getSubimage(x, y, w, h);
ImageIcon icon = new ImageIcon(img);
iconList.add(icon);
}
}
// get the Icon from the List at index position
public Icon getIcon(int index) {
if (index < 0 || index >= iconList.size()) {
throw new ArrayIndexOutOfBoundsException(index);
}
return iconList.get(index);
}
public int getIconListSize() {
return iconList.size();
}
}
Have you tried this?
public void mouseClicked(MouseEvent e)
{
sizes = new JFrame("Shopping");
sizes.add(l);
sizes.setVisible(true);
sizes.setSize(500, 500);
sizes.setLocation(100,200);
shirts.dispose();
//Remove the "e.getSource()" part.
}
It will automatically display the image, because you are assigning the Image Name to it, in the same segment as the Addition to the new JFrame.
Let me know of the outcome
I have implemented my own closeable JTabbedPane (essentially following advice from here - by extending JTabbedPane and overriding some methods and calling setTabComponentAt(...)). It works perfectly except one thing - when there are too many tabs to fit on one row (when there are 2 or more rows of tabs), the cross button/icon is not aligned to the right of the tab but it remains next to the tab title, which looks ugly. I've tried the demo from Java tutorials and it suffers from the same problem.
What I want is that the cross button/icon is always aligned to the very right, but the text is always aligned to the center. Can this be achieved by some layouting tricks? Note: I do not want to implement a custom TabbedPaneUI as this leads to other problems.
UPDATE I'm forced to use Java 6
The complete code is below, just run it and add 5 or more tabs.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
/**
* CloseableTabbedPane is a tabbed pane with a close icon on the right side of all tabs making it possible to close a tab.
* You can pass an instance of TabClosingListener to one of the constructors to react to tab closing.
*
* #author WiR
*/
public class CloseableTabbedPane extends JTabbedPane {
public static interface TabClosingListener {
/**
* #param aTabIndex the index of the tab that is about to be closed
* #return true if the tab can be really closed
*/
public boolean tabClosing(int aTabIndex);
/**
* #param aTabIndex the index of the tab that is about to be closed
* #return true if the tab should be selected before closing
*/
public boolean selectTabBeforeClosing(int aTabIndex);
}
private TabClosingListener tabClosingListener;
private String iconFileName = "images/cross.gif";
private String selectedIconFileName = "images/cross_selected.gif";
private static Icon CLOSING_ICON;
private static Icon CLOSING_ICON_SELECTED;
private class PaintedCrossIcon implements Icon {
int size = 10;
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.drawLine(x, y, x + size, y + size);
g.drawLine(x + size, y, x, y + size);
}
#Override
public int getIconWidth() {
return size;
}
#Override
public int getIconHeight() {
return size;
}
}
public CloseableTabbedPane() {
super();
}
public CloseableTabbedPane(TabClosingListener aTabClosingListener) {
super();
tabClosingListener = aTabClosingListener;
}
/**
* Sets the file name of the closing icon along with the optional variant of the icon when the mouse is over the icon.
*/
public void setClosingIconFileName(String aIconFileName, String aSelectedIconFileName) {
iconFileName = aIconFileName;
selectedIconFileName = aSelectedIconFileName;
}
/**
* Makes the close button at the specified indes visible or invisible
*/
public void setCloseButtonVisibleAt(int aIndex, boolean aVisible) {
CloseButtonTab cbt = (CloseButtonTab) getTabComponentAt(aIndex);
cbt.closingLabel.setVisible(aVisible);
}
#Override
public void insertTab(String title, Icon icon, Component component, String tip, int index) {
super.insertTab(title, icon, component, tip, index);
setTabComponentAt(index, new CloseButtonTab(component, title, icon));
}
#Override
public void setTitleAt(int index, String title) {
super.setTitleAt(index, title);
CloseButtonTab cbt = (CloseButtonTab) getTabComponentAt(index);
cbt.label.setText(title);
}
#Override
public void setIconAt(int index, Icon icon) {
super.setIconAt(index, icon);
CloseButtonTab cbt = (CloseButtonTab) getTabComponentAt(index);
cbt.label.setIcon(icon);
}
#Override
public void setComponentAt(int index, Component component) {
CloseButtonTab cbt = (CloseButtonTab) getTabComponentAt(index);
super.setComponentAt(index, component);
cbt.tab = component;
}
//note: setToolTipTextAt(int) must NOT be overridden !
private Icon getImageIcon(String aImageName) {
URL imageUrl = CloseableTabbedPane.class.getClassLoader().getResource(aImageName);
if (imageUrl == null) {
return new PaintedCrossIcon();
}
ImageIcon result = new ImageIcon(imageUrl);
if (result.getIconWidth() != -1) {
return result;
} else {
return null;
}
}
private class CloseButtonTab extends JPanel {
private Component tab;
private JLabel label;
private JLabel closingLabel;
public CloseButtonTab(Component aTab, String aTitle, Icon aIcon) {
tab = aTab;
setOpaque(false);
setLayout(new GridBagLayout());
setVisible(true);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(0, 0, 0, 5);
label = new JLabel(aTitle);
label.setIcon(aIcon);
add(label, gbc);
if (CLOSING_ICON == null) {
CLOSING_ICON = getImageIcon(iconFileName);
CLOSING_ICON_SELECTED = getImageIcon(selectedIconFileName);
}
closingLabel = new JLabel(CLOSING_ICON);
closingLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
JTabbedPane tabbedPane = (JTabbedPane) getParent().getParent();
int tabIndex = indexOfComponent(tab);
if (tabClosingListener != null) {
if (tabClosingListener.selectTabBeforeClosing(tabIndex)) {
tabbedPane.setSelectedIndex(tabIndex);
}
if (tabClosingListener.tabClosing(tabIndex)) {
tabbedPane.removeTabAt(tabIndex);
}
} else {
tabbedPane.removeTabAt(tabIndex);
}
}
#Override
public void mouseEntered(MouseEvent e) {
if (CLOSING_ICON_SELECTED != null) {
closingLabel.setIcon(CLOSING_ICON_SELECTED);
}
}
#Override
public void mouseExited(MouseEvent e) {
if (CLOSING_ICON_SELECTED != null) {
closingLabel.setIcon(CLOSING_ICON);
}
}
});
gbc.insets = new Insets(0, 0, 0, 0);
add(closingLabel, gbc);
}
}
static int count = 0;
/**
* For testing purposes.
*
*/
public static void main(String[] args) {
final JTabbedPane tabbedPane = new CloseableTabbedPane();
tabbedPane.addTab("test" + count, new JPanel());
count++;
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(tabbedPane, BorderLayout.CENTER);
JButton addButton = new JButton("Add tab");
addButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tabbedPane.addTab("test" + count, new JPanel());
count++;
}
});
mainPanel.add(addButton, BorderLayout.SOUTH);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 400);
frame.getContentPane().add(mainPanel);
frame.setVisible(true);
}
}
Here is one possible implementation using JLayer:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class CloseableTabbedPaneTest {
public JComponent makeUI() {
UIManager.put("TabbedPane.tabInsets", new Insets(2, 2, 2, 50));
final JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("aaaaaaaaaaaaaaaa", new JPanel());
tabbedPane.addTab("bbbbbbbb", new JPanel());
tabbedPane.addTab("ccc", new JPanel());
JPanel p = new JPanel(new BorderLayout());
p.add(new JLayer<JTabbedPane>(tabbedPane, new CloseableTabbedPaneLayerUI()));
p.add(new JButton(new AbstractAction("add tab") {
#Override public void actionPerformed(ActionEvent e) {
tabbedPane.addTab("test", new JPanel());
}
}), BorderLayout.SOUTH);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new CloseableTabbedPaneTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class CloseableTabbedPaneLayerUI extends LayerUI<JTabbedPane> {
private final JPanel p = new JPanel();
private final Point pt = new Point(-100, -100);
private final JButton button = new JButton("x") {
#Override public Dimension getPreferredSize() {
return new Dimension(16, 16);
}
};
public CloseableTabbedPaneLayerUI() {
super();
button.setBorder(BorderFactory.createEmptyBorder());
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setRolloverEnabled(false);
}
#Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c instanceof JLayer) {
JLayer jlayer = (JLayer) c;
JTabbedPane tabPane = (JTabbedPane) jlayer.getView();
for (int i = 0; i < tabPane.getTabCount(); i++) {
Rectangle rect = tabPane.getBoundsAt(i);
Dimension d = button.getPreferredSize();
int x = rect.x + rect.width - d.width - 2;
int y = rect.y + (rect.height - d.height) / 2;
Rectangle r = new Rectangle(x, y, d.width, d.height);
button.setForeground(r.contains(pt) ? Color.RED : Color.BLACK);
SwingUtilities.paintComponent(g, button, p, r);
}
}
}
#Override public void installUI(JComponent c) {
super.installUI(c);
((JLayer)c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
#Override public void uninstallUI(JComponent c) {
((JLayer)c).setLayerEventMask(0);
super.uninstallUI(c);
}
#Override protected void processMouseEvent(MouseEvent e, JLayer<? extends JTabbedPane> l) {
if (e.getID() == MouseEvent.MOUSE_CLICKED) {
pt.setLocation(e.getPoint());
JTabbedPane tabbedPane = (JTabbedPane) l.getView();
int index = tabbedPane.indexAtLocation(pt.x, pt.y);
if (index >= 0) {
Rectangle rect = tabbedPane.getBoundsAt(index);
Dimension d = button.getPreferredSize();
int x = rect.x + rect.width - d.width - 2;
int y = rect.y + (rect.height - d.height) / 2;
Rectangle r = new Rectangle(x, y, d.width, d.height);
if (r.contains(pt)) {
tabbedPane.removeTabAt(index);
}
}
l.getView().repaint();
}
}
#Override protected void processMouseMotionEvent(MouseEvent e, JLayer<? extends JTabbedPane> l) {
pt.setLocation(e.getPoint());
JTabbedPane tabbedPane = (JTabbedPane) l.getView();
int index = tabbedPane.indexAtLocation(pt.x, pt.y);
if (index >= 0) {
tabbedPane.repaint(tabbedPane.getBoundsAt(index));
} else {
tabbedPane.repaint();
}
}
}
Edit:
Here is an example using a GlassPane(Note: this is NOT tested at all):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CloseableTabbedPaneTest2 {
public JComponent makeUI() {
UIManager.put("TabbedPane.tabInsets", new Insets(2, 2, 2, 50));
final JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("aaaaaaaaaaaaaaaa", new JPanel());
tabbedPane.addTab("bbbbbbbb", new JPanel());
tabbedPane.addTab("ccc", new JPanel());
JPanel p = new JPanel(new BorderLayout());
//p.setBorder(BorderFactory.createLineBorder(Color.RED, 10));
p.add(tabbedPane);
p.add(new JButton(new AbstractAction("add tab") {
#Override public void actionPerformed(ActionEvent e) {
tabbedPane.addTab("test", new JScrollPane(new JTree()));
}
}), BorderLayout.SOUTH);
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
JPanel gp = new CloseableTabbedPaneGlassPane(tabbedPane);
tabbedPane.getRootPane().setGlassPane(gp);
gp.setOpaque(false);
gp.setVisible(true);
}
});
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new CloseableTabbedPaneTest2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class CloseableTabbedPaneGlassPane extends JPanel {
private final Point pt = new Point(-100, -100);
private final JButton button = new JButton("x") {
#Override public Dimension getPreferredSize() {
return new Dimension(16, 16);
}
};
private final JTabbedPane tabbedPane;
private final Rectangle buttonRect = new Rectangle(button.getPreferredSize());
public CloseableTabbedPaneGlassPane(JTabbedPane tabbedPane) {
super();
this.tabbedPane = tabbedPane;
MouseAdapter h = new Handler();
tabbedPane.addMouseListener(h);
tabbedPane.addMouseMotionListener(h);
button.setBorder(BorderFactory.createEmptyBorder());
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setRolloverEnabled(false);
}
#Override public void paintComponent(Graphics g) {
Point glassPt = SwingUtilities.convertPoint(tabbedPane, 0, 0, this);
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
Rectangle tabRect = tabbedPane.getBoundsAt(i);
int x = tabRect.x + tabRect.width - buttonRect.width - 2;
int y = tabRect.y + (tabRect.height - buttonRect.height) / 2;
buttonRect.setLocation(x, y);
button.setForeground(buttonRect.contains(pt) ? Color.RED : Color.BLACK);
buttonRect.translate(glassPt.x, glassPt.y);
SwingUtilities.paintComponent(g, button, this, buttonRect);
}
}
class Handler extends MouseAdapter {
#Override public void mouseClicked(MouseEvent e) {
pt.setLocation(e.getPoint());
int index = tabbedPane.indexAtLocation(pt.x, pt.y);
if (index >= 0) {
Rectangle tabRect = tabbedPane.getBoundsAt(index);
int x = tabRect.x + tabRect.width - buttonRect.width - 2;
int y = tabRect.y + (tabRect.height - buttonRect.height) / 2;
buttonRect.setLocation(x, y);
if (buttonRect.contains(pt)) {
tabbedPane.removeTabAt(index);
}
}
tabbedPane.repaint();
}
#Override public void mouseMoved(MouseEvent e) {
pt.setLocation(e.getPoint());
int index = tabbedPane.indexAtLocation(pt.x, pt.y);
if (index >= 0) {
tabbedPane.repaint(tabbedPane.getBoundsAt(index));
} else {
tabbedPane.repaint();
}
}
}
}
I'm using this one: http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java
The close button is painted by this itself so if can be placed anywhere.
Another problem, same program:
The following is MainGUI.java
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class MainGUI extends JFrame implements ActionListener
{
private static final long serialVersionUID = 4149825008429377286L;
private final double version = 8;
public static int rows;
public static int columns;
private int totalCells;
private MainCell[] cell;
public static Color userColor;
JTextField speed = new JTextField("250");
Timer timer = new Timer(250,this);
String generationText = "Generation: 0";
JLabel generationLabel = new JLabel(generationText);
int generation = 0;
public MainGUI(String title, int r, int c)
{
rows = r;
columns = c;
totalCells = r*c;
System.out.println(totalCells);
cell = new MainCell[totalCells];
setTitle(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Timer set up
timer.setInitialDelay(Integer.parseInt(speed.getText()));
timer.setActionCommand("timer");
//set up menu bar
JMenuBar menuBar = new JMenuBar();
JMenu optionsMenu = new JMenu("Options");
JMenu aboutMenu = new JMenu("About");
menuBar.add(optionsMenu);
menuBar.add(aboutMenu);
JMenuItem helpButton = new JMenuItem("Help!");
helpButton.addActionListener(this);
helpButton.setActionCommand("help");
aboutMenu.add(helpButton);
JMenuItem aboutButton = new JMenuItem("About");
aboutButton.addActionListener(this);
aboutButton.setActionCommand("about");
aboutMenu.add(aboutButton);
JMenuItem colorSelect = new JMenuItem("Select a Custom Color");
colorSelect.addActionListener(this);
colorSelect.setActionCommand("colorSelect");
optionsMenu.add(colorSelect);
JMenuItem sizeChooser = new JMenuItem("Define a Custom Size");
sizeChooser.addActionListener(this);
sizeChooser.setActionCommand("sizeChooser");
optionsMenu.add(sizeChooser);
//Create text field to adjust speed and its label
JPanel speedContainer = new JPanel();
JLabel speedLabel = new JLabel("Enter the speed of a life cycle (in ms):");
speedContainer.add(speedLabel);
speedContainer.add(speed);
speedContainer.add(generationLabel);
Dimension speedDim = new Dimension(100,25);
speed.setPreferredSize(speedDim);
//Create various buttons
JPanel buttonContainer = new JPanel();
JButton randomizerButton = new JButton("Randomize");
randomizerButton.addActionListener(this);
randomizerButton.setActionCommand("randomize");
buttonContainer.add(randomizerButton);
JButton nextButton = new JButton("Next"); //forces a cycle to occur
nextButton.addActionListener(this);
nextButton.setActionCommand("check");
buttonContainer.add(nextButton);
JButton startButton = new JButton("Start");
startButton.addActionListener(this);
startButton.setActionCommand("start");
buttonContainer.add(startButton);
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(this);
stopButton.setActionCommand("stop");
buttonContainer.add(stopButton);
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(this);
clearButton.setActionCommand("clear");
buttonContainer.add(clearButton);
//holds the speed container and button container, keeps it neat
JPanel functionContainer = new JPanel();
BoxLayout functionLayout = new BoxLayout(functionContainer, BoxLayout.PAGE_AXIS);
functionContainer.setLayout(functionLayout);
functionContainer.add(speedContainer);
speedContainer.setAlignmentX(CENTER_ALIGNMENT);
functionContainer.add(buttonContainer);
buttonContainer.setAlignmentX(CENTER_ALIGNMENT);
//finish up with the cell container
GridLayout cellLayout = new GridLayout(rows,columns);
JPanel cellContainer = new JPanel(cellLayout);
cellContainer.setBackground(Color.black);
int posX = 0;
int posY = 0;
for(int i=0;i<totalCells;i++)
{
MainCell childCell = new MainCell();
cell[i] = childCell;
childCell.setName(String.valueOf(i));
childCell.setPosX(posX);
posX++;
childCell.setPosY(posY);
if(posX==columns)
{
posX = 0;
posY++;
}
cellContainer.add(childCell);
childCell.deactivate();
Graphics g = childCell.getGraphics();
childCell.paint(g);
}
//make a default color
userColor = Color.yellow;
//change icon
URL imgURL = getClass().getResource("images/gol.gif");
ImageIcon icon = new ImageIcon(imgURL);
System.out.println(icon);
setIconImage(icon.getImage());
//add it all up and pack
JPanel container = new JPanel();
BoxLayout containerLayout = new BoxLayout(container, BoxLayout.PAGE_AXIS);
container.setLayout(containerLayout);
container.add(cellContainer);
container.add(functionContainer);
add(menuBar);
setJMenuBar(menuBar);
add(container);
pack();
}
private void checkCells()
{
//perform check for every cell
for(int i=0;i<totalCells;i++)
{
cell[i].setNeighbors(checkNeighbors(i));
}
//use value from check to determine life
for(int i=0;i<totalCells;i++)
{
int neighbors = cell[i].getNeighbors();
if(cell[i].isActivated())
{
System.out.println(cell[i].getName()+" "+neighbors);
if(neighbors==0||neighbors==1||neighbors>3)
{
cell[i].deactivate();
}
}
if(cell[i].isActivated()==false)
{
if(neighbors==3)
{
cell[i].activate();
}
}
}
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("randomize"))
{
Random rn = new Random();
for(int i=0;i<totalCells;i++)
{
cell[i].deactivate();
if(rn.nextInt(6)==0)
{
cell[i].activate();
}
}
}
//help button, self-explanatory
if(e.getActionCommand().equals("help"))
{
JOptionPane.showMessageDialog(this, "The game is governed by four rules:\nFor a space that is 'populated':"
+ "\n Each cell with one or no neighbors dies, as if by loneliness."
+ "\n Each cell with four or more neighbors dies, as if by overpopulation."
+ "\n Each cell with two or three neighbors survives."
+ "\nFor a space that is 'empty' or 'unpopulated':"
+ "\n Each cell with three neighbors becomes populated."
+ "\nLeft click populates cells. Right click depopulates cells.","Rules:",JOptionPane.PLAIN_MESSAGE);
}
//shameless self promotion
if(e.getActionCommand().equals("about"))
{
JOptionPane.showMessageDialog(this, "Game made and owned by *****!"
+ "\nFree usage as see fit, but give credit where credit is due!\nVERSION: "+version,"About:",JOptionPane.PLAIN_MESSAGE);
}
//clears all the cells
if(e.getActionCommand().equals("clear"))
{
timer.stop();
generation = 0;
generationText = "Generation: "+generation;
generationLabel.setText(generationText);
for(int i=0;i<totalCells;i++)
{
cell[i].deactivate();
}
}
//starts timer
if(e.getActionCommand().equals("start"))
{
if(Integer.parseInt(speed.getText())>0)
{
timer.setDelay(Integer.parseInt(speed.getText()));
timer.restart();
}
else
{
JOptionPane.showMessageDialog(this, "Please use a value greater than 0!","Rules:",JOptionPane.ERROR_MESSAGE);
}
}
//stops timer
if(e.getActionCommand().equals("stop"))
{
timer.stop();
}
//run when timer
if(e.getActionCommand().equals("timer"))
{
generation++;
generationText = "Generation: "+generation;
generationLabel.setText(generationText);
timer.stop();
checkCells();
timer.setInitialDelay(Integer.parseInt(speed.getText()));
timer.restart();
}
//see checkCells()
if(e.getActionCommand().equals("check"))
{
generation++;
generationText = "Generation: "+generation;
generationLabel.setText(generationText);
checkCells();
}
//color select gui
if(e.getActionCommand().equals("colorSelect"))
{
userColor = JColorChooser.showDialog(this, "Choose a color:", userColor);
if(userColor==null)
{
userColor = Color.yellow;
}
}
//size chooser!
if(e.getActionCommand().equals("sizeChooser"))
{
SizeChooser size = new SizeChooser();
size.setLocationRelativeTo(null);
size.setVisible(true);
}
}
private int checkNeighbors(int c)
{
//if a LIVE neighbor is found, add one
int neighbors = 0;
if(cell[c].getPosX()!=0&&cell[c].getPosY()!=0)
{
if(c-columns-1>=0)
{
if(cell[c-columns-1].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c-columns-1].getName());
neighbors++;
}
}
}
if(cell[c].getPosY()!=0)
{
if(c-columns>=0)
{
if(cell[c-columns].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c-columns].getName());
neighbors++;
}
}
}
if(cell[c].getPosX()!=columns-1&&cell[c].getPosY()!=0)
{
if(c-columns+1>=0)
{
if(cell[c-columns+1].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c-columns+1].getName());
neighbors++;
}
}
}
if(cell[c].getPosX()!=0)
{
if(c-1>=0)
{
if(cell[c-1].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c-1].getName());
neighbors++;
}
}
}
if(cell[c].getPosX()!=columns-1)
{
if(c+1<totalCells)
{
if(cell[c+1].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c+1].getName());
neighbors++;
}
}
}
if(cell[c].getPosX()!=0&&cell[c].getPosY()!=rows-1)
{
if(c+columns-1<totalCells)
{
if(cell[c+columns-1].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c+columns-1].getName());
neighbors++;
}
}
}
if(cell[c].getPosY()!=rows-1&&cell[c].getPosY()!=rows-1)
{
if(c+columns<totalCells)
{
if(cell[c+columns].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c+columns].getName());
neighbors++;
}
}
}
if(cell[c].getPosX()!=columns-1&&cell[c].getPosY()!=rows-1)
{
if(c+columns+1<totalCells)
{
if(cell[c+columns+1].isActivated())
{
System.out.println(cell[c].getName()+" found "+cell[c+columns+1].getName());
neighbors++;
}
}
}
return neighbors;
}
}
The following is MainCell.java:
public class MainCell extends JPanel implements MouseListener
{
//everything here should be self-explanatory
private static final long serialVersionUID = 1761933778208900172L;
private boolean activated = false;
public static boolean leftMousePressed;
public static boolean rightMousePressed;
private int posX = 0;
private int posY = 0;
private int neighbors = 0;
private URL cellImgURL_1 = getClass().getResource("images/cellImage_1.gif");
private ImageIcon cellImageIcon_1 = new ImageIcon(cellImgURL_1);
private Image cellImage_1 = cellImageIcon_1.getImage();
private URL cellImgURL_2 = getClass().getResource("images/cellImage_2.gif");
private ImageIcon cellImageIcon_2 = new ImageIcon(cellImgURL_2);
private Image cellImage_2 = cellImageIcon_2.getImage();
private URL cellImgURL_3 = getClass().getResource("images/cellImage_3.gif");
private ImageIcon cellImageIcon_3 = new ImageIcon(cellImgURL_3);
private Image cellImage_3 = cellImageIcon_3.getImage();
public MainCell()
{
Dimension dim = new Dimension(17, 17);
setPreferredSize(dim);
addMouseListener(this);
}
public void activate()
{
setBackground(MainGUI.userColor);
System.out.println(getName()+" "+posX+","+posY+" activated");
setActivated(true);
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if(getPosX()==MainGUI.columns-1&&getPosY()==0)
{
//do nothing
}
else if(getPosY()!=0&&getPosX()!=MainGUI.columns-1)
{
g.drawImage(cellImage_1,0,0,null);
}
else if(getPosY()==0)
{
g.drawImage(cellImage_2,0,0,null);
}
else if(getPosX()==MainGUI.columns-1)
{
g.drawImage(cellImage_3,0,0,null);
}
}
public void setActivated(boolean b)
{
activated = b;
}
public void deactivate()
{
setBackground(Color.gray);
System.out.println(getName()+" "+posX+","+posY+" deactivated");
setActivated(false);
}
public boolean isActivated()
{
return activated;
}
public void setNeighbors(int i)
{
neighbors = i;
}
public int getNeighbors()
{
return neighbors;
}
public int getPosX()
{
return posX;
}
public void setPosX(int x)
{
posX = x;
}
public int getPosY()
{
return posY;
}
public void setPosY(int y)
{
posY = y;
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
if(leftMousePressed&&SwingUtilities.isLeftMouseButton(e))
{
activate();
}
if(rightMousePressed&&SwingUtilities.isRightMouseButton(e))
{
deactivate();
}
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
if(SwingUtilities.isRightMouseButton(e)&&!leftMousePressed)
{
deactivate();
rightMousePressed = true;
}
if(SwingUtilities.isLeftMouseButton(e)&&!rightMousePressed)
{
activate();
leftMousePressed = true;
}
}
public void mouseReleased(MouseEvent e)
{
if(SwingUtilities.isRightMouseButton(e))
{
rightMousePressed = false;
}
if(SwingUtilities.isLeftMouseButton(e))
{
leftMousePressed = false;
}
}
}
The following is SizeChooser.java:
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.swing.*;
public class SizeChooser extends JFrame
{
private static final long serialVersionUID = -6431709376438241788L;
public static MainGUI GUI;
private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
JTextField rowsTextField = new JTextField(String.valueOf((screenSize.height/17)-15));
JTextField columnsTextField = new JTextField(String.valueOf((screenSize.width/17)-10));
private static int rows = screenSize.height/17-15;
private static int columns = screenSize.width/17-10;
public SizeChooser()
{
setResizable(false);
setTitle("Select a size!");
JPanel container = new JPanel();
BoxLayout containerLayout = new BoxLayout(container, BoxLayout.PAGE_AXIS);
container.setLayout(containerLayout);
add(container);
JLabel rowsLabel = new JLabel("Rows:");
container.add(rowsLabel);
container.add(rowsTextField);
JLabel columnsLabel = new JLabel("Columns:");
container.add(columnsLabel);
container.add(columnsTextField);
JButton confirmSize = new JButton("Confirm");
confirmSize.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
GUI.setVisible(false);
GUI = null;
if(Integer.parseInt(rowsTextField.getText())>0)
{
rows = Integer.parseInt(rowsTextField.getText());
}
else
{
JOptionPane.showMessageDialog(rootPane, "Please use a value greater than 0!","Rules:",JOptionPane.ERROR_MESSAGE);
}
if(Integer.parseInt(columnsTextField.getText())>0)
{
columns = Integer.parseInt(columnsTextField.getText());
}
else
{
JOptionPane.showMessageDialog(rootPane, "Please use a value greater than 0!","Rules:",JOptionPane.ERROR_MESSAGE);
}
GUI = new MainGUI("The Game of Life!", rows, columns);
GUI.setLocationRelativeTo(null);
GUI.setVisible(true);
setVisible(false);
}
});
container.add(confirmSize);
URL imgURL = getClass().getResource("images/gol.gif");
ImageIcon icon = new ImageIcon(imgURL);
System.out.println(icon);
setIconImage(icon.getImage());
pack();
}
public static void main(String[]args)
{
GUI = new MainGUI("The Game of Life!", rows, columns);
GUI.setLocationRelativeTo(null);
GUI.setVisible(true);
}
}
So the problem now is, when the randomize button is pressed, or a large number of cells exist and then the timer is started, the cells aren't as snappy as they would be with less active cells. For example, with 100 columns and 50 rows, when the randomize button is pressed, one cell activates, then the next, then another, and so forth. Can I have them all activate at exactly the same time? Is this just a problem with too many things calculated at once? Would concurrency help?
QUICK EDIT: Is the swing timer the best idea for this project?
I havent read through your code completely but I am guessing that your listener methods are fairly computationally intensive and hence the lag in updating the display.
This simple test reveals that your randomize operation should be fairly quick:
public static void main(String args[]) {
Random rn = new Random();
boolean b[] = new boolean[1000000];
long timer = System.nanoTime();
for (int i = 0; i < b.length; i++) {
b[i] = rn.nextInt(6) == 0;
}
timer = System.nanoTime() - timer;
System.out.println(timer + "ns / " + (timer / 1000000) + "ms");
}
The output for me is:
17580267ns / 17ms
So this leads me into thinking activate() or deactivate() is causing your UI to be redrawn.
I am unable to run this because I don't have your graphical assets, but I would try those changes to see if it works:
In MainGUI#actionPerformed, change:
if(e.getActionCommand().equals("randomize"))
{
Random rn = new Random();
for(int i=0;i<totalCells;i++)
{
cell[i].deactivate();
if(rn.nextInt(6)==0)
{
cell[i].activate();
}
}
}
to:
if(e.getActionCommand().equals("randomize"))
{
Random rn = new Random();
for(int i=0;i<totalCells;i++)
{
// This will not cause the object to be redrawn and should
// be a fairly cheap operation
cell[i].setActivated(rn.nextInt(6)==0);
}
// Cause the UI to repaint
repaint();
}
Add this to MainCell
// You can specify those colors however you like
public static final Color COLOR_ACTIVATED = Color.RED;
public static final Color COLOR_DEACTIVATED = Color.GRAY;
And change:
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if(getPosX()==MainGUI.columns-1&&getPosY()==0)
{
//do nothing
}
to:
protected void paintComponent(Graphics g)
{
// We now make UI changes only when the component is painted
setBackground(activated ? COLOR_ACTIVATED : COLOR_DEACTIVATED);
super.paintComponent(g);
if(getPosX()==MainGUI.columns-1&&getPosY()==0)
{
//do nothing
}
JProgressBar in JProgressBar.VERTICAL mode rotates painted String.
Is it possible to save string HORIZONTAL?
Another option is to use a BorderLayout + JLabel
or if you are using Java 1.7.0, you can use a JLayer
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.LayerUI;
public class ProgressBarLabelTest {
private static JProgressBar makeProgressBar1(BoundedRangeModel model) {
JProgressBar progressBar = new JProgressBar(model) {
private JLabel label = new JLabel("000/100", SwingConstants.CENTER);
private ChangeListener changeListener = null;
#Override public void updateUI() {
removeAll();
if(changeListener!=null) removeChangeListener(changeListener);
super.updateUI();
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
setLayout(new BorderLayout());
changeListener = new ChangeListener() {
#Override public void stateChanged(ChangeEvent e) {
int iv = (int)(100 * getPercentComplete());
label.setText(String.format("%03d/100", iv));
}
};
addChangeListener(changeListener);
add(label);
label.setBorder(BorderFactory.createEmptyBorder(0,4,0,4));
}
});
}
#Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
Insets i = label.getInsets();
d.width = label.getPreferredSize().width + i.left + i.right;
return d;
}
};
initProgressBar(progressBar);
return progressBar;
}
private static JComponent makeProgressBar2(BoundedRangeModel model) {
final JLabel label = new JLabel("000/100");
label.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
LayerUI<JProgressBar> layerUI = new LayerUI<JProgressBar>() {
private final JPanel rubberStamp = new JPanel();
#Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
Dimension d = label.getPreferredSize();
int x = (c.getWidth() - d.width) / 2;
int y = (c.getHeight() - d.height) / 2;
JLayer jlayer = (JLayer)c;
JProgressBar progress = (JProgressBar)jlayer.getView();
int iv = (int)(100 * progress.getPercentComplete());
label.setText(String.format("%03d/100", iv));
SwingUtilities.paintComponent(
g, label, rubberStamp, x, y, d.width, d.height);
}
};
JProgressBar progressBar = new JProgressBar(model) {
#Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
Insets i = label.getInsets();
d.width = label.getPreferredSize().width + i.left + i.right;
return d;
}
};
initProgressBar(progressBar);
return new JLayer<JProgressBar>(progressBar, layerUI);
}
public JComponent makeUI() {
final BoundedRangeModel m = new DefaultBoundedRangeModel();
JProgressBar progressBar0 = new JProgressBar(m);
initProgressBar(progressBar0);
progressBar0.setStringPainted(true);
JPanel p = new JPanel();
p.add(progressBar0);
p.add(makeProgressBar1(m));
p.add(makeProgressBar2(m));
p.add(new JButton(new AbstractAction("+10") {
private int i = 0;
#Override public void actionPerformed(ActionEvent e) {
m.setValue(i = (i>=100) ? 0 : i + 10);
}
}));
return p;
}
private static void initProgressBar(JProgressBar progressBar) {
progressBar.setOrientation(SwingConstants.VERTICAL);
progressBar.setStringPainted(false);
progressBar.setForeground(Color.GREEN);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() { createAndShowGUI(); }
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new ProgressBarLabelTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
It is a true-Hack but if works for me:
I lookup in the Stack if UI asks for orientation while printing the label, if so I return another orientation.
JProgressBar progress = new JProgressBar(){
#Override
public int getOrientation() {
for( StackTraceElement elem : new Throwable().getStackTrace() ) {
if(elem.getMethodName().equals( "paintText" ) || (elem.getMethodName().equals( "paintString" ))) {
return JProgressBar.HORIZONTAL;
}
}
return JProgressBar.VERTICAL;
}
};
You can override paintString() in a custom BasicProgressBarUI. A related example is seen here.