Apply MVC to a Swing app?

Folks,
I got inspired by this thread: http://forum.java.sun.com/thread.jspa?threadID=5244847&start=23&tstart=0
and wrote the below version of MineSweeper (winmine.exe) in Swing as a learning exercise.
I'm about half way through my TODO list, and the code is "getting ugly". For instance, It took me a couple of hours to figure out what needed to change in order to keep track of the remaining bombs.
This leads me to believe that the best way forward might be to declare this version to be "The Prototype" and go back to torres.... taking what I've learned about the problems involved, and designing the whole thing from ground up, applying the MVC paradigm.
But I'm really unsure of how go about doing that... I studied program design back in the heyday of pseudo-code and structure charts, and I was hoping for some free advise (pretty please) or maybe some practical exercises/tutorials on OO program design. I've read some theory, but to be honest, it just goes over my head... in one ear and out the other. I hope that exercise of applying the principles espoused in the theory to a concrete example will help me to bring the theory into focus... at the moment GOF is rattling around in my brain, but it refuses coalesce into a coherent picture.
I have a rough design in mind... Please would anyone care to comment?
The Model
* A Field has Mine's
* Field would contain a matrix of Mine's ... mines[col][row]
* Mine would encapsulate the state of each mine, and expose the a low level set of mutators.
The View
* Form extends JFrame - the main form
* Top JPanel - much like the existing one
* Bottom JPanel
.... I'm wondering if a JTable would work in place of the existing matrix of JPanels.
.... or can this be done with a LayoutManager... I'm thinking GridBagLayout?
* Can I use a JPanel instead of the existing JPanel contains a JButton?
.... * I've got an issue with the existing MouseListener implementation. You have to hold
.... the mouse still and click each button rather deliberately. This ruins the fluidity of
.... the game-play, substantially reducing the players enjoyment. ie: it gives me the sh1ts.
.... Please does anyone have any ideas? I've used enough swing/awt apps to know
.... that this isn't an insoluble problem, but I've got no idea how to address it.
The Controler
* A Game class orchestrates the whole thing at the high level.
... + main - Creates a new Game and calls it's play method.
... - play - Creates and shows the gui on the EDT
* The MineLayer lays Mine's for the MineSweeper to clean up.
.... But I'm a but lost as to what should "own" the MineLayer and the MineSweeper.
.... To me it makes sense for the Controler to kick of the View, but from then on
.... we're event-driven by the View... so should the View "create and own" the
.... MineLayer and the MineSweeper? or should they be created by the controler
.... and passed into the constructor of the main form? This OO stuff always leaves me
.... feeling a bit thick. Back in my day you just called functions. It was ugly and simple.
.... OO is ugly and complicated.
package krc.games;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import java.awt.EventQueue;
import java.awt.Container;
import java.awt.Color;
import java.awt.Insets;
import java.awt.Font;
import java.awt.BorderLayout;
import java.awt.image.ColorModel;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import javax.swing.border.LineBorder;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
// TODO:
// * implement "you win"... track remaining bombs.                DONE
// * show "not a bomb" at end of game.                            DONE
// * display remaining bombs.                                     DONE
// * display a clock.                                             DONE
// * Resign/Refactor along MVC lines.
//   M = A Field has Mine's
//   V = The JFrame, some JPanels, a Grid?
//   C = Game orchestrates. The MineLayer lays Mine's for the MineSweeper to clean up.
// * beginner / intermediate / advanced / custom settings.
//   - Find out how to use menu's in swing
// * config board from command line args and/or properties file.
//   - Use an XML Properties file.
// * restart the same game. Reset the board with existing bombs. 
//   - TOO EASY - remember the seed used passed to Random.
// * high score.
//   - CAPTURE: JOptionPane("Enter your name")
//   - DISPLAY: A form with a grid
//   - STORE  : Java only database
// * save and load a game.
//   - A de/serialization exercise.
// * cheats - IDDKFA ;-)
//   - keyboard listener to show bombs.
import java.awt.image.BufferedImage;
public class MineSweeperGame extends JFrame
  private static final long serialVersionUID = 0L;
  private static final int ROWS = 15;
  private static final int COLS = 30;
  private static final int BOMBS = (int)(ROWS * COLS / 4.5);
  private JLabel bombs = null; //count down the bombs
  private int bombsRemaining = BOMBS;
  private JLabel clock = null; //seconds since first click
  private int elapsedTime;
  private volatile boolean isClockRunning = false;
  private static final String DIR = "C:/Java/home/src/krc/games/";
  private static final BufferedImage FLAG_IMAGE     = loadImage(DIR+"/flag.jpg");
  private static final BufferedImage QUESTION_IMAGE = loadImage(DIR+"/question.jpg");
  private static final BufferedImage BOMB_IMAGE     = loadImage(DIR+"/bomb.jpg");
  private static final BufferedImage EXPLODED_IMAGE = loadImage(DIR+"/exploded_bomb.jpg");
  private static final BufferedImage NOT_BOMB_IMAGE = loadImage(DIR+"/not_bomb.jpg");
  // number colors
  private static final Color[] COLORS = {
    Color.black         // 0 not used
  , Color.blue          // 1 blue
  , new Color(0,153,153)// 4 darkGreen
  , Color.red           // 3 red
  , new Color(0,0,204)  // 4 darkBlue
  , new Color(153,0,0)  // 5 brown
  , Color.pink          // 6 pink
  , Color.orange        // 7 orange
  , Color.white         // 8 white
  , Color.magenta       // 9 magenta
  private static final Font FONT = new Font("Dialog", Font.BOLD, 12);
  private MouseListener mouseListener = new MouseAdapter() {
    public void mouseClicked(MouseEvent event) {
      if(!isClockRunning) startClock();
      Cell cell = ((Cell.Button)event.getSource()).getParentCell();
      if ( event.getButton() == MouseEvent.BUTTON1 ) {
        if (cell.isBomb()) {
          if ( cell.isMarkedAsBomb() ) {
            java.awt.Toolkit.getDefaultToolkit().beep();
          } else {
            cell.explode();
            youLost();
        } else {
          revealCell(cell);
      } else if ( event.getButton() == MouseEvent.BUTTON3 ) {
        cell.nextState();
  private class Cell extends JPanel {
    private static final long serialVersionUID = 0L;
    public static final int WIDTH = 17;
    public static final int HEIGHT = 17;
    public static final float Y_OFFSET = 13F;
    public static final float X_OFFSET = 5F;
    private class Button extends JButton {
      private static final long serialVersionUID = 0L;
      private final Cell parentCell;
      public Button(int width, int height, Cell parentCell) {
        this.parentCell = parentCell;
        this.setBounds(0, 0, width, height);
        this.setMargin(new Insets(1,1,1,1));
        this.setFont(new Font("Dialog",0,8));
        this.addMouseListener(mouseListener); // handle right button
      public void reset() {
        this.setText("");
        this.setVisible(true);
        this.setIcon(null);
      public Cell getParentCell() {
        return this.parentCell;
    private final Button button;
    private final int row, col;
    private boolean isBomb = false;
    private boolean isRevealed = false;
    private boolean isExploded = false;
    private int neighbours = 0;
    private ImageIcon[] stateIcons = new ImageIcon[] {
      null,  new ImageIcon(FLAG_IMAGE), new ImageIcon(QUESTION_IMAGE)
    private int state = 0;
    public static final int STATE_UNMARKED = 0;
    public static final int STATE_MARKED_AS_A_BOMB = 1;
    public static final int STATE_MARKED_AS_A_QUESTION = 2;
    Cell(int row, int col) {
      this.row = row;
      this.col = col;
      this.setBounds(col*WIDTH, row*HEIGHT, WIDTH, HEIGHT);
      this.setLayout(null);
      button = new Button(WIDTH, HEIGHT, this);
      this.add(button);
    public boolean isBomb() { return this.isBomb; }
    public void setBomb(boolean isBomb) { this.isBomb = isBomb; }
    public boolean isRevealed() { return this.isRevealed; }
    public void reveal() {
      if(this.isRevealed) return;
      this.button.setVisible(false);
      this.isRevealed = true;
    public void revealNotABomb() {
      button.setText("");
      button.setIcon(new ImageIcon(NOT_BOMB_IMAGE));
    public boolean isExploded() { return this.isExploded; }
    public void explode() {this.isExploded = true;}
    public int getNeighbours() { return this.neighbours; }
    public void setNeighbours(int neighbours) {this.neighbours = neighbours;}
    public void reset() {
      this.isRevealed = false;
      this.isBomb = false;
      this.isExploded = false;
      this.state = STATE_UNMARKED;
      this.button.reset();
    public boolean isMarkedAsBomb() {
      return this.state == Cell.STATE_MARKED_AS_A_BOMB;
    public void nextState() {
      boolean wasMarkedAsABomb = this.isMarkedAsBomb();
      this.state = (this.state+1) % 3;
      button.setIcon(stateIcons[this.state]);
      if (this.isMarkedAsBomb()) {
        setBombsRemaining(getBombsRemaining()-1);
        if (getBombsRemaining() == 0) {
          if (allMarkedBombsAreReallyBombs()) {
            youWon();
          } else {
            youLost();
      } else if (wasMarkedAsABomb) {
        setBombsRemaining(getBombsRemaining()+1);
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      if ( this.isRevealed() ) {
        Graphics2D g2d = (Graphics2D) g;
        if (this.isExploded) {
          g2d.drawImage(EXPLODED_IMAGE, 0, 0, null);
        } else if (this.isBomb) {
          g2d.drawImage(BOMB_IMAGE, 0, 0, null);
        } else if (this.neighbours > 0) {
          g2d.setColor(COLORS[this.neighbours]);
          g2d.setFont(FONT);
          g2d.drawString(""+this.neighbours, X_OFFSET, Y_OFFSET);
  private Cell[][] cells = new Cell[ROWS][COLS];
  MineSweeperGame() {
    super();
    buildAndShowGUI();
  private void buildAndShowGUI() {
    this.setTitle("Miner");
    final int CELLS_X = Cell.WIDTH*COLS;
    final int WASTE_X = 6;
    final int WIN_WIDTH = CELLS_X+WASTE_X;
    final int CELLS_Y = Cell.HEIGHT*ROWS;
    final int WASTE_Y = 32;
    final int TOP_FRAME_Y = 34;
    final int WIN_HEIGHT = CELLS_Y+WASTE_Y+TOP_FRAME_Y;
    this.setSize(WIN_WIDTH, WIN_HEIGHT);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setResizable(false);
    Container pane = this.getContentPane();
    pane.setLayout(null);
    JPanel top = new JPanel();
    top.setBounds(0,0, WIN_WIDTH,TOP_FRAME_Y);
    top.setBorder(new LineBorder(Color.black));
    top.setLayout(null);
    bombs = new JLabel();
    bombs.setBounds(5,7, 23,17);
    bombs.setBorder(new LineBorder(Color.black));
    top.add(bombs);
    clock = new JLabel("0");
    clock.setBounds(WIN_WIDTH-35,7, 23,17);
    clock.setBorder(new LineBorder(Color.black));
    top.add(clock);
    pane.add(top);
    JPanel bot = new JPanel();
    bot.setLayout(null);
    bot.setBackground(Color.white);
    bot.setBounds(0, TOP_FRAME_Y+1, CELLS_X, CELLS_Y);
    for(int r=0; r<ROWS; r++) {
      for(int c=0; c<COLS; c++) {
        cells[r][c] = new Cell(r, c);
        bot.add(cells[r][c]);
    pane.add(bot);
    resetGame();
    this.setVisible(true);
  private void resetGame() {
    resetClock();
    resetCells();
    placeBombs();
    setBombsRemaining(BOMBS);
    countNeighbouringBombs();
  private void resetCells() {
    // reset all the cells
    for(int r=0; r<ROWS; r++) {
      for(int c=0; c<COLS; c++) {
        cells[r][c].reset();
  private void placeBombs() {
    // randomly place however many bombs in the minefield
    Random rand = new Random(System.currentTimeMillis());
    for(int i=0; i<BOMBS; i++) {
      while(true) {
        Cell cell = this.cells[rand.nextInt(ROWS)][rand.nextInt(COLS)];
        if (!cell.isBomb()) {
          cell.setBomb(true);
          cell.button.setText("b");
          break;
  // count the number of bombs neighbouring each cell
  private void countNeighbouringBombs() {
    for(int r=0; r<ROWS; r++) {
      for(int c=0; c<COLS; c++) {
        cells[r][c].setNeighbours(getNeighbourCount(r, c));
  // the number of bombs neighbouring the given cell
  private int getNeighbourCount(int row, int col) {
    int count = 0;
    int firstRow = Math.max(row-1, 0);
    int lastRow  = Math.min(row+1, ROWS-1);
    int firstCol = Math.max(col-1, 0);
    int lastCol  = Math.min(col+1, COLS-1);
    for(int r=firstRow; r<=lastRow; r++) {
      for(int c=firstCol; c<=lastCol; c++) {
        if( this.cells[r][c].isBomb ) count++;
    return count;
  public void setBombsRemaining(int bombsRemaining) {
    this.bombsRemaining = bombsRemaining;
    this.bombs.setText(""+this.bombsRemaining);
  public int getBombsRemaining() {
    return(this.bombsRemaining);
  private void showBombs() {
    for(int r=0; r<ROWS; r++) {
      for(int c=0; c<COLS; c++) {
        Cell cell = cells[r][c];
        if (cell.isBomb) {
          cell.reveal();
        } else if (cell.isMarkedAsBomb()) {
          cell.revealNotABomb();
  private boolean allMarkedBombsAreReallyBombs() {
    for(int r=0; r<ROWS; r++) {
      for(int c=0; c<COLS; c++) {
        Cell cell = this.cells[r][c];
        if (cell.isMarkedAsBomb() && !cell.isBomb() ) {
          return false;
    return true;
  private void revealCell(Cell cell) {
    if(cell.getNeighbours()==0) {
      revealCells(cell, new HashMap<Cell,Object>());
    } else {
      cell.reveal();
  private void revealCells(Cell cell, Map<Cell,Object> ancestors) {
    if (ancestors.containsKey(cell)) return;
    if (cell.isRevealed()) return;
    ancestors.put(cell, null);
    cell.reveal();
    if(cell.getNeighbours()==0) {
      int firstRow = Math.max(cell.row-1, 0);
      int lastRow  = Math.min(cell.row+1, ROWS-1);
      int firstCol = Math.max(cell.col-1, 0);
      int lastCol  = Math.min(cell.col+1, COLS-1);
      for(int r=firstRow; r<=lastRow; r++) {
        for(int c=firstCol; c<=lastCol; c++) {
          Cell x = cells[r][c];
          if (x == cell) continue;
          if( !x.isBomb() && !x.isRevealed() ) {
            revealCells(x, ancestors);
  private void youLost() {
    stopClock();
    showBombs();
    JOptionPane.showMessageDialog(this, "You Lost.", "Game Over", JOptionPane.WARNING_MESSAGE);
    resetGame();
  private void youWon() {
    stopClock();
    JOptionPane.showMessageDialog(this, "You Won. Congratulations.", "Game Over", JOptionPane.INFORMATION_MESSAGE);
    resetGame();
  private static BufferedImage loadImage(String filename) {
    try {
      return ImageIO.read(new File(filename));
    } catch (IOException e) {
      // the game will still kinda work, you just won't see this image.
      e.printStackTrace();
    return null;
  private void startClock() {
    isClockRunning = true;
    new Thread() {
      public void run() {
        while (isClockRunning) {
          clock.setText(""+(elapsedTime++));
          //repaint();
          try{Thread.sleep(1000);}catch(InterruptedException eaten){}
    }.start();
  private void stopClock() {
    this.isClockRunning = false;
  private void resetClock() {
    elapsedTime = 0;
    clock.setText("0");
  public static void main(String[] args) {
    try {
      EventQueue.invokeLater(
        new Runnable() {
          public void run() {
            MineSweeperGame game = new MineSweeperGame();
    } catch (Exception e) {
      e.printStackTrace();
}Thanx in advance for any ideas.
Cheers. Keith.
Edited by: corlettk on Dec 23, 2007 6:15 AM - typos.

For anyone who's interested... here's the latest (and complete, I think) version of the program.... there's quit a lot of code here, sorry. It should all compile first time... but you'll need to scrape your own set of images from minesweeper (ie: winmine.exe) and google for the wav files... It's a shame we can't post jar's or zip's here.
MineSweeperGame.java
package krc.games.sweeper;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.ButtonGroup;
import java.awt.Color;
import java.awt.Insets;
import java.awt.Font;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import javax.swing.border.LineBorder;
import java.io.File;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.HashMap;
import java.util.Map;
import krc.utilz.sound.WavePlayer;
// TODO:
// * implement "you win"... track remaining bombs.                    DONE
// * show "not a bomb" at end of game.                                DONE
// * display remaining bombs.                                         DONE
// * display a clock.                                                 DONE
// * Resign/Refactor along MVC lines.                                 NOT DONE
//   M = A Field has Mine's
//   V = The JFrame, some JPanels, a Grid?
//   C = Controler orcestrates.
// * beginner / intermediate / advanced / custom settings.            DONE
//   - Find out how to use menu's in swing
// * config board from command line args and/or properties file.      DONE
//   - used a standard properties file
// * restart the same game. Reset the board with existing bombs.      DONE
//   - TOO EASY - remember the seed used passed to Random.
// * high score.
//   - CAPTURE: JOptionPane("Enter your name")
//   - DISPLAY: A form with a grid
//   - STORE  : Java only database
// * save and load a game.
//   - A de/serialization exercise.
// * cheats
//   until the first 0 is hit
//   - ctrl-click - is bomb proof (costs 5 seconds)                   DONE
//   - fifth click reveals the biggest patch of 0's                   DONE
//   god mode
//   - ctrl-alt-shift shows the position of all bombs.                DONE
//     // search for "b" - uncomment that line)
public class MineSweeperGame extends JFrame
  private static final long serialVersionUID = 0L;
  //these are read from properties files
  private GameSettings settings;
  private JFrame theFrame;
  private JLabel bombs = null; //count down the bombs
  private int bombsRemaining;
  private boolean replayCurrentGame = false;
  private long randomSeed = 0;
  private GameClock clock = null; //seconds since first click
  private static final String DIR = "C:/Java/home/src/krc/games/sweeper/";
  private static final String IMGDIR = DIR+"images/";
  private static final BufferedImage FLAG_IMAGE     = loadImage(IMGDIR+"flag.jpg");
  private static final BufferedImage QUESTION_IMAGE = loadImage(IMGDIR+"question.jpg");
  private static final BufferedImage BOMB_IMAGE     = loadImage(IMGDIR+"bomb.jpg");
  private static final BufferedImage EXPLODED_IMAGE = loadImage(IMGDIR+"exploded_bomb.jpg");
  private static final BufferedImage NOT_BOMB_IMAGE = loadImage(IMGDIR+"not_bomb.jpg");
  private static final String WAVDIR = DIR+"sounds/";
  // number colors
  private static final Color[] COLORS = {
    Color.black         // 0 not used
  , Color.blue          // 1 blue
  , new Color(0,153,153)// 4 darkGreen
  , Color.red           // 3 red
  , new Color(0,0,204)  // 4 darkBlue
  , new Color(153,0,0)  // 5 brown
  , Color.pink          // 6 pink
  , Color.orange        // 7 orange
  , Color.white         // 8 white
  , Color.magenta       // 9 magenta
  private static final Font FONT = new Font("Dialog", Font.BOLD, 12);
  private class GameMenuBar extends JMenuBar
    private static final long serialVersionUID = 0L;
    private ActionListener menuListener = new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        String action = event.getActionCommand().toLowerCase();
        if ("new".equals(action)) {
          hideAndDestroyGUI();
          buildAndShowGUI();
        } else if ("restart".equals(action)) {
          hideAndDestroyGUI();
          replayCurrentGame = true;
          buildAndShowGUI();
        } else if ( "beginner,intermediate,expert,custom".indexOf(action) > -1 ) {
          hideAndDestroyGUI();
          if ( "custom".equals(action) ) {
            CustomSettingsDialog dialog = new CustomSettingsDialog(theFrame, properties.get("custom"));
            settings = dialog.getSettings();
            dialog.dispose();
            properties.set(settings);
          } else {
            settings = properties.get(action);
          buildAndShowGUI();
        } else if ("exit".equals(action)) {
          setVisible(false);
          dispose();
        } else {
          java.awt.Toolkit.getDefaultToolkit().beep();
          System.out.println("Menu item ["+event.getActionCommand()+"] was pressed.");
    public GameMenuBar(String level) {
      JMenu menu = new JMenu("Game");
      menu.add(newJMenuItem("New", 'N'));
      menu.add(newJMenuItem("Restart", 'R'));
      menu.addSeparator();
      ButtonGroup group = new ButtonGroup();
      menu.add(newJRadioButtonMenuItem(group, "Beginner", level));
      menu.add(newJRadioButtonMenuItem(group, "Intermediate", level));
      menu.add(newJRadioButtonMenuItem(group, "Expert", level));
      menu.add(newJRadioButtonMenuItem(group, "Custom", level));
      menu.addSeparator();
      menu.add(newJMenuItem("Exit", 'X'));
      this.add(menu);
    private JMenuItem newJMenuItem(String text, char mneumonic) {
      JMenuItem item = new JMenuItem(text, mneumonic);
      item.addActionListener(this.menuListener);
      return item;
    private JRadioButtonMenuItem newJRadioButtonMenuItem(ButtonGroup group, String text, String level) {
      JRadioButtonMenuItem item = new JRadioButtonMenuItem(text);
      item.addActionListener(this.menuListener);
      group.add(item);
      if(text.equalsIgnoreCase(level)) item.setSelected(true);
      return item;
  private class Cell extends JPanel
    private static final long serialVersionUID = 0L;
    public static final int WIDTH = 17;
    public static final int HEIGHT = 17;
    public static final float Y_OFFSET = 13F;
    public static final float X_OFFSET = 5F;
    private class Button extends JButton {
      private static final long serialVersionUID = 0L;
      private final Cell parentCell;
      public Button(int width, int height, Cell parentCell) {
        this.parentCell = parentCell;
        this.setBounds(0, 0, width, height);
        this.setMargin(new Insets(1,1,1,1));
        this.setFont(new Font("Dialog",0,8));
        this.addMouseListener(mouseListener); // handles left & right button
      public void reset() {
        this.setText("");
        this.setVisible(true);
        this.setIcon(null);
      public Cell getParentCell() {
        return this.parentCell;
      public void removeMouseListener() {
        this.removeMouseListener(mouseListener);
    private final Button button;
    private final int row, col;
    private boolean isBomb = false;
    private boolean isRevealed = false;
    private boolean isExploded = false;
    private int neighbours = 0;
    public static final int STATE_UNMARKED = 0;
    public static final int STATE_MARKED_AS_A_BOMB = 1;
    public static final int STATE_MARKED_AS_A_QUESTION = 2;
    private int state = 0;
    private ImageIcon[] stateIcons = new ImageIcon[] {
      null,  new ImageIcon(FLAG_IMAGE), new ImageIcon(QUESTION_IMAGE)
    Cell(int row, int col) {
      this.row = row;
      this.col = col;
      this.setBounds(col*WIDTH, row*HEIGHT, WIDTH, HEIGHT);
      this.setLayout(null);
      button = new Button(WIDTH, HEIGHT, this);
      this.add(button);
    public boolean isBomb() { return this.isBomb; }
    public void setBomb(boolean isBomb) { this.isBomb = isBomb; }
    public boolean isRevealed() { return this.isRevealed; }
    public void reveal() {
      if(this.isRevealed) return;
      this.button.setVisible(false);
      this.isRevealed = true;
    public void revealNotABomb() {
      button.setText("");
      button.setIcon(new ImageIcon(NOT_BOMB_IMAGE));
    public boolean isExploded() { return this.isExploded; }
    public void explode() {this.isExploded = true;}
    public int getNeighbours() { return this.neighbours; }
    public void setNeighbours(int neighbours) {this.neighbours = neighbours;}
    public void reset() {
      this.isRevealed = false;
      this.isBomb = false;
      this.isExploded = false;
      this.state = STATE_UNMARKED;
      this.button.reset();
    public boolean isMarkedAsBomb() {
      return this.state == Cell.STATE_MARKED_AS_A_BOMB;
    public void nextState() {
      boolean wasMarkedAsABomb = this.isMarkedAsBomb();
      this.state = (this.state+1) % 3;
      button.setIcon(stateIcons[this.state]);
      if (this.isMarkedAsBomb()) {
        setBombsRemaining(getBombsRemaining()-1);
        if (getBombsRemaining() == 0) {
          if (allMarkedBombsAreReallyBombs()) {
            youWon();
          } else {
            youLost();
      } else if (wasMarkedAsABomb) {
        setBombsRemaining(getBombsRemaining()+1);
    public void removeMouseListener() {
      button.removeMouseListener();
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      if ( this.isRevealed() ) {
        Graphics2D g2 = (Graphics2D) g;
        if (this.isExploded) {
          g2.drawImage(EXPLODED_IMAGE, 0, 0, null);
        } else if (this.isBomb) {
          g2.drawImage(BOMB_IMAGE, 0, 0, null);
        } else if (this.neighbours > 0) {
          g2.setColor(COLORS[this.neighbours]);
          g2.setFont(FONT);
          g2.drawString(""+this.neighbours, X_OFFSET, Y_OFFSET);
  private MouseListener mouseListener = null;
  private GameProperties properties = null;
  private Cell[][] cells = null;
  // this game is a "virgin" until the user finds the first 0.
  private boolean isVirgin = false;
  // when the user clears fifth square of a virgin game the
  // largest patch of 0's is automagically cleared.
  private int numCleared = 0;
  MineSweeperGame() {
    theFrame = this;
    this.properties = new GameProperties();
    this.settings = this.properties.get();
    buildAndShowGUI();
  private void setMouseListener(){
    this.mouseListener = new MouseAdapter() {
      public void mouseClicked(MouseEvent event) {
        clock.start();
        Cell cell = ((Cell.Button)event.getSource()).getParentCell();
        if ( event.getButton() == MouseEvent.BUTTON1 ) {
          if(event.isControlDown()) clock.skip(5);
          if (cell.isBomb()) {
            if ( cell.isMarkedAsBomb() ) {
              java.awt.Toolkit.getDefaultToolkit().beep();
            } else if ( event.isControlDown() ) {
              WavePlayer.play(WAVDIR+"ricochet.wav");
            } else {
              WavePlayer.play(WAVDIR+"grenade.wav");
              cell.explode();
              youLost();
          } else {
            revealCell(cell);
            if ( isVirgin && ++numCleared==5 ) {
              WavePlayer.play(WAVDIR+"smokin.wav");
              revealTheBiggestFreePatch();
        } else if ( event.getButton() == MouseEvent.BUTTON3 ) {
          cell.nextState();
  private void hideAndDestroyGUI() {
    this.setVisible(false);
    for(int r=0; r<settings.rows; r++) {
      for(int c=0; c<settings.cols; c++) {
        cells[r][c].removeMouseListener(); // old mouse listeners send it crazy.
        cells[r][c] = null;
    this.getContentPane().removeAll();
    this.dispose();
  private void buildAndShowGUI() {
    final int CELLS_X = Cell.WIDTH*settings.cols;
    final int WASTE_X = 9;
    final int WIN_WIDTH = CELLS_X+WASTE_X;
    final int CELLS_Y = Cell.HEIGHT*settings.rows;
    final int WASTE_Y = 59;
    final int TOP_FRAME_Y = 34;
    final int WIN_HEIGHT = CELLS_Y+WASTE_Y+TOP_FRAME_Y;
    this.setTitle("Miner");
    this.setSize(WIN_WIDTH, WIN_HEIGHT);
    this.setResizable(false);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setJMenuBar( new GameMenuBar(this.settings.level) );
    this.getContentPane().setLayout(null);
    // the top panel
    JPanel top = new JPanel(null);
    top.setBounds(0,0, WIN_WIDTH-6,TOP_FRAME_Y);
    top.setBorder(new LineBorder(Color.black));
    // the remaining-bomb-counter (on the left)
    bombs = new JLabel();
    bombs.setBounds(5,7, 23,17);
    bombs.setBorder(new LineBorder(Color.black));
    top.add(bombs);
    // the time-counter (on the right)
    this.clock = new GameClock();
    clock.setBounds(WIN_WIDTH-35,7, 23,17);
    top.add(clock);
    this.getContentPane().add(top);
    // the bottom panel
    setMouseListener();
    JPanel bot = new JPanel();
    bot.setLayout(null);
    bot.setBackground(Color.white);
    bot.setBounds(0, TOP_FRAME_Y+1, CELLS_X, CELLS_Y);
    this.cells = new Cell[settings.rows][settings.cols];
    for(int r=0; r<settings.rows; r++) {
      for(int c=0; c<settings.cols; c++) {
        cells[r][c] = new Cell(r, c);
        bot.add(cells[r][c]);
    this.getContentPane().add(bot);
    resetGame();
    this.setVisible(true);
  private void resetGame() {
    clock.reset();
    resetCells();
    isVirgin = true;
    numCleared = 0;
    placeBombs();
    setBombsRemaining(settings.bombs);
    countNeighbouringBombs();
  // reset the state of all the cells to default "empty" values.
  private void resetCells() {
    for(int r=0; r<settings.rows; r++) {
      for(int c=0; c<settings.cols; c++) {
        cells[r][c].reset();
  // randomly place however many bombs in the minefield
  // if replay then reuses the same seed to reproduce the same mine layout.
  private void placeBombs() {
    if(!this.replayCurrentGame) this.randomSeed = System.currentTimeMillis();
    this.replayCurrentGame = false;
    Random rand = new Random(this.randomSeed);
    for(int i=0; i<settings.bombs; i++) {
      while(true) {
        Cell cell = this.cells[rand.nextInt(settings.rows)][rand.nextInt(settings.cols)];
        if (!cell.isBomb()) {
          cell.setBomb(true);
          //cell.button.setText("b");
          break;
  // count the number of bombs neighbouring each cell
  private void countNeighbouringBombs() {
    for(int r=0; r<settings.rows; r++) {
      for(int c=0; c<settings.cols; c++) {
        cells[r][c].setNeighbours(getNeighbourCount(r, c));
  // return the number of bombs neighbouring the given cell
  private int getNeighbourCount(int row, int col) {
    int count = 0;
    int firstRow = Math.max(row-1, 0);
    int lastRow  = Math.min(row+1, settings.rows-1);
    int firstCol = Math.max(col-1, 0);
    int lastCol  = Math.min(col+1, settings.cols-1);
    for(int r=firstRow; r<=lastRow; r++) {
      for(int c=firstCol; c<=lastCol; c++) {
        if( this.cells[r][c].isBomb ) count++;
    return count;
  public void setBombsRemaining(int bombsRemaining) {
    this.bombsRemaining = bombsRemaining;
    this.bombs.setText(""+this.bombsRemaining);
  public int getBombsRemaining() {
    return(this.bombsRemaining);
  private void showBombs() {
    for(int r=0; r<settings.rows; r++) {
      for(int c=0; c<settings.cols; c++) {
        Cell cell = cells[r][c];
        if (cell.isBomb) {
          cell.reveal();
        } else if (cell.isMarkedAsBomb()) {
          cell.revealNotABomb();
  private boolean allMarkedBombsAreReallyBombs() {
    for(int r=0; r<settings.rows; r++) {
      for(int c=0; c<settings.cols; c++) {
        Cell cell = this.cells[r][c];
        if (cell.isMarkedAsBomb() && !cell.isBomb() ) {
          return false;
    return true;
  private void revealCell(Cell cell) {
    if(cell.getNeighbours()==0) {
      revealCells(cell, new HashMap<Cell,Object>());
    } else {
      cell.reveal();
  private void revealTheBiggestFreePatch() {
    Map<Cell,Object> counted = new HashMap<Cell,Object>();
    int count = 0;
    int max = 0;
    Cell maxCell = null;
    for(int r=0; r<settings.rows; r++) {
      for(int c=0; c<settings.cols; c++) {
        Cell cell = this.cells[r][c];
        if(cell.getNeighbours()==0) {
          count = countNeighbouringZeros(cell, counted);
          if(count > max) {
            max = count;
            maxCell = cell;
    revealCell(maxCell);
  private int countNeighbouringZeros(Cell cell, Map<Cell,Object> counted) {
    int count = 0;
    if (counted.containsKey(cell)) return 0;
    counted.put(cell, null);
    if(cell.getNeighbours()==0) {
      count++;
      int firstRow = Math.max(cell.row-1, 0);
      int lastRow  = Math.min(cell.row+1, settings.rows-1);
      int firstCol = Math.max(cell.col-1, 0);
      int lastCol  = Math.min(cell.col+1, settings.cols-1);
      for(int r=firstRow; r<=lastRow; r++) {
        for(int c=firstCol; c<=lastCol; c++) {
          Cell x = cells[r][c];
          if (x == cell) continue;
          if (x.getNeighbours()==0) {
            count += countNeighbouringZeros(x, counted);
    return count;
  private void revealCells(Cell cell, Map<Cell,Object> ancestors) {
    if (ancestors.containsKey(cell)) return;
    if (cell.isRevealed()) return;
    ancestors.put(cell, null);
    cell.reveal();
    if(cell.getNeighbours()==0) {
      isVirgin = false;
      int firstRow = Math.max(cell.row-1, 0);
      int lastRow  = Math.min(cell.row+1, settings.rows-1);
      int firstCol = Math.max(cell.col-1, 0);
      int lastCol  = Math.min(cell.col+1, settings.cols-1);
      for(int r=firstRow; r<=lastRow; r++) {
        for(int c=firstCol; c<=lastCol; c++) {
          Cell x = cells[r][c];
          if (x == cell) continue;
          if( !x.isBomb() && !x.isRevealed() ) {
            revealCells(x, ancestors);
  private void youLost() {
    clock.stop();
    showBombs();
    //WavePlayer.play(WAVDIR+"msstartup.wav");
    Object[] options = { "Replay", "New Game" };
    int choice = JOptionPane.showOptionDialog(
        null
      , "Replay?"
      , "Game Over."
      , JOptionPane.DEFAULT_OPTION
      , JOptionPane.QUESTION_MESSAGE
      , null
      , options
      , options[0]
    if (choice == 0) {
      replayCurrentGame = true;
    resetGame();
  private void youWon() {
    clock.stop();
    WavePlayer.play(WAVDIR+"applause.wav");
    JOptionPane.showMessageDialog(this, "Congratulations. You Won!", "Game Over", JOptionPane.INFORMATION_MESSAGE);
    resetGame();
  private static BufferedImage loadImage(String filename) {
    try {
      return ImageIO.read(new File(filename));
    } catch (Exception e) { //IOExcecption
      // the game will still kinda work, you just won't see the images.
      e.printStackTrace();
    return null;
  public static void main(String[] args) {
    java.awt.EventQueue.invokeLater(
      new Runnable() {
        public void run() {
          MineSweeperGame game = new MineSweeperGame();
CustomSettingsDialog.java
package krc.games.sweeper;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class CustomSettingsDialog extends JDialog implements ActionListener
  private static final long serialVersionUID = 0L;
  private static final int ROW_HEIGHT = 24;
  private static final int PAD = 5;
  private boolean isOk = false;
  GameSettings settings;
  private JPanel panel;
  private JTextField rowsTextField;
  private JTextField colsTextField;
  private JTextField bombsTextField;
  private JButton okButton;
  private JButton cancelButton;
  CustomSettingsDialog(JFrame parentFrame, GameSettings settings) {
    super(parentFrame, true);
    this.settings = settings;
    this.setTitle("Custom Miner");
    this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    this.setSize(250, 200);
    this.setResizable(false);
    panel = new JPanel();
    panel.setLayout(null);
    addLabel(0, "rows"); rowsTextField = addField(0, ""+settings.rows);
    addLabel(1, "cols"); colsTextField = addField(1, ""+settings.cols);
    addLabel(2, "bombs"); bombsTextField = addField(2, ""+settings.bombs);
    okButton = addButton(3,0, "Ok");
    cancelButton = addButton(3,1, "Cancel");
    rowsTextField.selectAll();
    rowsTextField.requestFocusInWindow();
    this.add(panel);
    this.setVisible(true);
  boolean isOk() {
    return this.isOk;
  GameSettings getSettings() {
    return this.settings;
  private void addLabel(int row, String caption) {
    JLabel label = new JLabel(caption);
    label.setBounds(PAD, PAD+((ROW_HEIGHT+PAD)*row), 80, ROW_HEIGHT);
    panel.add(label);
  private JTextField addField(int row, String text) {
    JTextField field = new JTextField();
    field.setBounds(80, PAD+((ROW_HEIGHT+PAD)*row), 100, ROW_HEIGHT);
    field.setText(text);
    panel.add(field);
    return(field);
  private JButton addButton(int row, int col, String caption) {
    JButton button = new JButton(caption);
    button.setBounds(20+(col*85), PAD+((ROW_HEIGHT+PAD)*row), 80, ROW_HEIGHT);
    button.addActionListener(this);
    panel.add(button);
    return(button);
  public void actionPerformed(ActionEvent event) {
    if ( okButton == event.getSource() ) {
      try {
        this.settings.level = "custom";
        this.settings.rows = Integer.parseInt(rowsTextField.getText());
        this.settings.cols = Integer.parseInt(colsTextField.getText());
        this.settings.bombs = Integer.parseInt(bombsTextField.getText());
        this.isOk = true;
        this.setVisible(false);
      } catch(NumberFormatException e) {
        JOptionPane.showMessageDialog(this, e.getMessage(), "NumberFormatException", JOptionPane.ERROR_MESSAGE);
    } else if ( cancelButton == event.getSource() ) {
      this.isOk = false;
      this.setVisible(false);
    } else {
      java.awt.Toolkit.getDefaultToolkit().beep();
      System.out.println("CustomSettingsDialog.actionPerformed: Unknown event source "+event.getSource());
GameProperties.java
package krc.games.sweeper;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
class GameProperties extends java.util.Properties
  private static final long serialVersionUID = 0L;
  private static final String FILENAME = "MineSweeperGame.properties";
  public GameProperties() {
    super();
    load();
  public GameSettings get(String level) {
    return new GameSettings(
        level
      , getInt(level+"_rows")
      , getInt(level+"_cols")
      , getInt(level+"_bombs")
  public GameSettings get() {
    return get(getProperty("level"));
  public void set(GameSettings settings) {
    setProperty("level", settings.level);
    setProperty(settings.level+"_rows", ""+settings.rows);
    setProperty(settings.level+"_cols", ""+settings.cols);
    setProperty(settings.level+"_bombs", ""+settings.bombs);
  public void load() {
    try {
      load(new FileReader(FILENAME));
    } catch (Exception e) {
      System.err.println("Failed to load properties from "+FILENAME+" - "+e);
      e.printStackTrace();
  public void save() {
    try {
      store(new FileWriter(FILENAME), FILENAME);
    } catch (Exception e) {
      System.err.println("Failed to save properties to "+FILENAME+" - "+e);
      e.printStackTrace();
  private int getInt(String key) {
    try {
      return Integer.parseInt(getProperty(key));
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException("Failed to getPropertyAsInt("+key+") from "+FILENAME+" - "+e);
GameSettings.java
package krc.games.sweeper;
class GameSettings
  public String level;
  public int rows;
  public int cols;
  public int bombs;
  GameSettings(String level, int rows, int cols, int bombs) {
    this.level = level;
    this.rows = rows;
    this.cols = cols;
    this.bombs = bombs;
GameClock.java
package krc.games.sweeper;
import javax.swing.JLabel;
import javax.swing.border.LineBorder;
import java.awt.Color;
class GameClock extends JLabel
  private static final long serialVersionUID = 0L;
  private volatile boolean isRunning = false;
  private volatile int elapsedTime;
  public GameClock() {
    super("0");
    elapsedTime = 0;
    this.setBorder(new LineBorder(Color.black));
  public void start() {
    if(isRunning) return;
    isRunning = true;
    new Thread() {
      public void run() {
        while (isRunning) {
          setText(""+(elapsedTime++));
          try{Thread.sleep(1000);}catch(InterruptedException eaten){}
    }.start();
  public void stop() {
    this.isRunning = false;
  public void skip(int seconds) {
    elapsedTime+=seconds;
  public void reset() {
    elapsedTime = 0;
    super.setText("0");
MineSweeperGame.properties
#MineSweeperGame.properties
#Sat Dec 29 18:56:47 GMT+10:00 2007
level=expert
beginner_rows=9
beginner_cols=9
beginner_bombs=10
intermediate_rows=16
intermediate_cols=16
intermediate_bombs=40
expert_rows=16
expert_cols=30
expert_bombs=99
custom_rows=30
custom_cols=50
custom_bombs=299-----
BTW... I gave up on the whole refactor thing... I just couldn't work out how to cleanly separate the view from the model... and my design was getting mighty complicated.... bigger than ben hurr... So I decided to revert to the "hack" version, and do a little refactoring to try to split out the more-easily-split-out sections, and tada - I (mostly) got through the TODO list.
Also... can anyone point me at a good serialization tutorial... sun's is a bit how's your dad.
Thanx all.

Similar Messages

  • Building Swing app in Ant

    I use IntelliJ as my IDE and when building my swing app through IntelliJ, the application works fine. However when I build it use Ant, I get a NullPointerException in the main thread. Is there anything special that needs to be done for Swing apps when compiling with Ant.

    Try using an MVC architecture, where the view is the JTree and the model is the treeModel. Make the treeModel implement Observable , and then use the Observable/Observer mechanism to notify the view of updates. Make sure the updates of the treeModel happen in a separate thread, not in the AWT event thread.
    Hope this helps

  • How to create printable report from a swing app.

    Hi,
    I have googled quite a bit and have searched the forum extensively but haven't found answers to my questions.
    I have a small swing based application (that uses jtextfields, jbuttons, jlist, etc) that collects information from user
    and stores in some variables; which are like strings, integers, hashmap, etc.
    Now this information is to be formatted and is to be printed as a report.
    Formatted as in, some part of the collected text is to be printed in certain font and other in different color and so on.
    Also the report is to be printed on a paper leaving some space at left and at the top. That means margins need to be set.
    And before all info is to be sent to printer I need to display this information in some report viewer (preview).
    How can I format certain text and set margins? (Is there some Document kind of api which allows me to set margins, change font of certain text?)
    How should I display this text / information as a print preview? (Should I use jeditorpane / jtextpane ?)
    How should I send all the information to the printer? (What java api should be used for printing?)
    The data entered by the user is not saved / persisted to any database. It's to be sent to the printer after submit button is pressed on the swing app.
    Since there is no database I couldn't use jasper-reports.
    Following are links to all threads (not useful) I found when I searched for swing / print / report in the forum :
    http://forums.sun.com/thread.jspa?forumID=331&threadID=225351
    http://forums.sun.com/thread.jspa?forumID=57&threadID=576758
    http://forums.sun.com/thread.jspa?forumID=57&threadID=570629
    http://forums.sun.com/thread.jspa?forumID=1&threadID=489905
    http://forums.sun.com/thread.jspa?forumID=57&threadID=571093
    http://forums.sun.com/thread.jspa?forumID=257&threadID=138450
    http://forums.sun.com/thread.jspa?forumID=57&threadID=583150
    http://forums.sun.com/thread.jspa?forumID=57&threadID=5399572
    http://forums.sun.com/thread.jspa?forumID=57&threadID=579619
    http://forums.sun.com/thread.jspa?forumID=57&threadID=593199
    Help would be much appreciated.

    alan_mehio wrote:
    The simplest thing to do in your case is to load the file content into the JTextArea
    then to create the header and the footer if there is any from java.text.MessageFormat
    then you invoke the print method on the JTextArea instance object> Just let me know if you are face any furrher problem
    Alan Mehio,
    I have been able to set margins and get the printout just the way I want it (after some experiments / trial & error).
    But the problem is, parameters to paper.setImageableArea() are hard coded as in the example code below :
            System.out.println("print?");
            PrinterJob printJob = PrinterJob.getPrinterJob();
            if (printJob.printDialog()) {
                PageFormat pf = printJob.defaultPage();
                Paper paper = pf.getPaper();
                paper.setSize(8.5 * 72, 11 * 72);
                System.out.println("paper width : " + paper.getWidth());// expecting 612
                System.out.println("paper height : " + paper.getHeight());// expecting 792
                System.out.println("ImageableHeight : " + paper.getImageableHeight());
                System.out.println("imageable width : " + paper.getImageableWidth());
                System.out.println("ImageableX : " + paper.getImageableX());
                System.out.println("Imageable y : " + paper.getImageableY());
                //paper.setImageableArea(108, 144, paper.getWidth() - 108, paper.getHeight() - 144);
                paper.setImageableArea(222, 244, paper.getWidth() - 222, paper.getHeight() - 244);
                pf.setPaper(paper);
                printJob.setPrintable(jTextArea1.getPrintable(null, null), pf);
                try {
                    printJob.print();
                } catch (Exception ex) {
                    System.out.println("exception while printing...");
                    ex.printStackTrace();
            }In my case the left margin should be 1.5 inches (38.1mm) and top margin should be 2 inches (50.8 mm)
    Considering 72dpi printer for a A4 size page (8.5in X 11in), the parameters to paper.setImageableArea() should be
    (108, 144, paper.getWidth() - 108, paper.getHeight() - 144);
    But the printout leaves only 1inch for top and left margins.
    Here are o/p lines for method-call with above said params :
    paper width : 612.0
    paper height : 792.0
    ImageableHeight : 648.0
    imageable width : 468.0
    ImageableX : 72.0
    Imageable y : 72.0
    When I pass the following values I get text printed with desired margins on the paper but the above printlns remain exactly the same!
    paper.setImageableArea(222.4, 244, paper.getWidth() - 222.4, paper.getHeight() - 244);
    Although I have been able to achieve what I wanted to without using 3rd party libraries,
    I feel this hard coding of values isn't a good idea and leaves a doubt whether this will work on other systems with different printers.
    My question is, how to get these numbers correct every time? Is there a formula for obtaining these numbers?
    Also formatting of certain part of to-print text is something that is yet to be figured out.
    Thanks.

  • Keyboard Problem while running Swing App on LINUX

    Hi All,
    We have a Swing based Application running on Windows Platform. We need to run the Application on LINUX. The Application does not have any problem and runs without problems for a few minutes but after that the keyboard stops to respond inside the application. Keyboard runs fine outside the application but no key events are recognized inside the application. Mouse is working fine even after the keyboard stops responding.
    Key Points:
    �     The keyboard is a PS/2 keyboard.
    �     Read Hat Fedora 5.0 is being used.
    �     The problems occur on both KDE and GNONE.
    �     The Java Version is jdk1.5.0_09
    The application is data entry application using EJB at server side. The client UI has lot of JTables and Desktop Panes/ Internal Frames. User use ctrl+tab, ctrl+shift+tab, tab, shift+tab, and other hot keys to navigate between Components. Listeners on keyboard Focus Owner are also used. We are unable to diagnose the problem because of the undeterminable nature of the problem. The problem occurs at anytime and does not occur on any special key/ combinations press.
    Thanks and Regards,
    Nishant Saini
    http://www.simplyjava.com

    I've just installed the JDK 1.4 on my debian box. I
    can compile and run a basic Hello World app using
    System.println, but when I try to run a simple swing
    app, I get an error like:
    Exception in thread "main"
    java.lang.NoClassDefFoundError
    at java.lang.Class.forName0(Native Method)
    at java.lang.... etc, etc.
    It goes on with about 30 different classes. It
    compiles fine, with no errors, but when it comes time
    to run, that's what I get. This is what I have in my
    .bash_profile as far as environment variables go:
    export JAVA_HOME="/usr/local/j2sdk1.4.1_01"
    export PATH="$JAVA_HOME/BIN:$PATH"
    export
    CLASSPATH="$JAVA_HOME/jre/lib/:$JAVA_HOME/lib:."The code works fine in Windows, so unless there's
    something platform-specific, I don't think there's a
    problem there. I've checked to make sure I'm not
    running kaffe by accident and I'm definitely running
    the right java and javac. I'm out of ideas. Any
    suggestions would be greatly appreciated.
    -dudley
    I may just be crazy, but your PATH looks a little screwy to me. I was under the impression that the standard java installation has its executables in the 'bin' directory, not the 'BIN' directory. Unless Debian has fallen to the evil empire, then I'm fairly sure file names are case-sensitive. I don't know if that will fix your problem though. Do you compile from the command line, or do you use an IDE???

  • ServiceLocator for swing app

    can anyone show me way how to speedup ejb invocation from remote swing app?
    I read about servicelocator for jsp application, but can no find topic about remote swing app servicelocator.
    my network call to remote ejb methods is dramatically slow :(
    thanks !

    Yes, good question, on my remote app it is very slow too....

  • Launching Swing apps in foreground remotely

    We have an agent that runs on our machines waiting to start and stop java applications, but there is a problem when the application has a GUI element to it. We are using the RunTime classes and it executes applications in the background which means that GUIs cannot be seen even though they are running.
    What is the secret to automatically launching java swing apps in the foreground?
    Thanks in advance.

    Replying to myself, as I think I've just found the answer (at least for an windows environment)
    --> Just start your app with "javaw" instead of "java"
    (What would be the right way to do it in Linux, for instance?)
    Joao Clemente

  • Swing app keyboard stops working, mystery ESCAPE keystrokes appear in EDT

    Java 6 Swing app. In our development environment, works great. In QA, they use it for a bit, type in a text field, click out to a Windows XP/7 app, click back in the text field, and the keyboard stops accepting keystrokes. The mouse continues to work, and the Swing app continues to paint to the screen.
    I hooked up a KeyEventDispatcher to listen to what is going on. I'll post a more verbose log at the end of this post, but the short version is this. When the keyboard hangs, the log shows that 'escape' keys are being sent, though we do not do any keystroke injection in our app, ESCAPE or otherwise. Nothing on the Swing app can be determined visually to have focus.
    Just before the app starts hanging, it has a side effect of not being able to be brought into the foreground by clicking on it, if, for example, one was working with Excel or Notepad, then try to click on the JFrame title of the app, or anywhere else on the app frame/internals. Once this condition happens, moving away to another Windows app, then going back to the Swing app, causes the keyboard to stop working and the KeyEventDispatcher to see 'escape' keystrokes being sent out.
    Connecting remotely to the app via JVisualVM/JConsole does not show any of the threads hanging/blocked.
    Sometimes you can work for hours before seeing this problem, and other times, you can start the app up and it happens right away. Once it happens, sometimes you can't recover, and sometimes you can click on a button on a navigator panel on the left side that displays an info panel on the right side, and you can start typing again in text fields.
    Once this problem happens, you can start (or have already running) a completely different Swing app (ex.: StackTrace), and the keyboard will stop working for that app too, even though its running in its own separate VM.
    This problem (ALMOST!) always happen when typing in a Swing text field (JTextField, JTextArea, etc.), clicking on and then typing in a Windows text area (Excel cell, Notepad), then clicking back into the Swing app's text field. A few times, we've gotten this to happen by typing in a text field, tabbing to a button, pressing a button, then tabbing/clicking back into the text field, all without leaving the Swing app. But this latter scenario is rare, usually going to/from Swing/Windows XP/7 apps cause the problem to occur more readily.
    The QA computers normally use Citrix to connect and run the app, but this also happens if we run the app completely locally. But again, this only happens to some computers, all of the ones in the QA department; the development computers (the app has not been released into production yet) does not see this problem.
    I had thought that our problem was this problem (Wrong characters in KeyEvents generated from input of barcode scanner but purposely slowing down the acceptance of KEY_PRESSED and KEY_RELEASED events before allowing them to go on to the Swing app (via a KeyDispatcher) did not solve the problem.
    Also, we had thought it might be a Citrix problem and how it (or does it?) hook into the Windows keyboard. The fact that once one Swing app gets into this keyboard doesn't work and escape keys are being sent out by the EDT can affect another Swing app makes me wonder. We're not seeing any VM exceptions either like this (EXCEPTION_ACCESS_VIOLATION - JRE 6.0_23 - Citrix, windows 2003
    Been trying to get this one solved for over a week, but with no luck. Any help/advice would be appreciated. Thank you in advance for your time.
    P.S. Here's the detailed log info I generated via my KeyEventDispatch listener...
    2011-04-01 11:58:17,493 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:36 - KEY1-keystroke [java.awt.DefaultKeyboardFocusManager@377369]: java.awt.event.KeyEvent[KEY_PRESSED,keyCode=27,keyText=Escape,keyChar=Escape,keyLocation=KEY_LOCATION_STANDARD,rawCode=27,primaryLevelUnicode=27,scancode=1] on javax.swing.JTextField[,320,28,175x18,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.ep.skin.lnf.framework.utils.internal.RoundedBorder@c3a7c0,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=15,columnWidth=11,command=,horizontalAlignment=LEADING]
    2011-04-01 11:58:17,494 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:42 - KEY2-ActiveWindow: javax.swing.JFrame[mainFrame,128,128,1024x768,invalid,layout=java.awt.BorderLayout,title=My - HQ - 17601,resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,1024x768,invalid,layout=com.ep.skin.lnf.framework.internal.RootPaneUI$MetalRootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource@d0e678,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
    2011-04-01 11:58:17,496 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:48 - KEY3-CurrentFocusCycleRoot: javax.swing.JFrame[mainFrame,128,128,1024x768,invalid,layout=java.awt.BorderLayout,title=My - HQ - 17601,resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,1024x768,invalid,layout=com.ep.skin.lnf.framework.internal.RootPaneUI$MetalRootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource@d0e678,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
    2011-04-01 11:58:17,497 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:54 - KEY4-FocusedWindow: javax.swing.JFrame[mainFrame,128,128,1024x768,invalid,layout=java.awt.BorderLayout,title=My - HQ - 17601,resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,1024x768,invalid,layout=com.ep.skin.lnf.framework.internal.RootPaneUI$MetalRootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource@d0e678,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
    2011-04-01 11:58:17,498 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:60 - KEY5-FocusOwner: javax.swing.JTextField[,320,28,175x18,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.ep.skin.lnf.framework.utils.internal.RoundedBorder@c3a7c0,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=15,columnWidth=11,command=,horizontalAlignment=LEADING]
    2011-04-01 11:58:17,499 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:66 - KEY6-PermanentFocusOwner: javax.swing.JTextField[,320,28,175x18,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.ep.skin.lnf.framework.utils.internal.RoundedBorder@c3a7c0,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=15,columnWidth=11,command=,horizontalAlignment=LEADING]
    2011-04-01 11:58:17,501 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:74 - KEY7-stacktrace...
    com..client.util.MyKeyEventDispatcher$StackTraceGenerationException: This exception was created to generate a stack trace, and can be safely ignored.
         at com..client.util.MyKeyEventDispatcher.dispatchKeyEvent(MyKeyEventDispatcher.java:73)
         at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
         at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
         at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
         at java.awt.Component.dispatchEventImpl(Unknown Source)
         at java.awt.Container.dispatchEventImpl(Unknown Source)
         at java.awt.Window.dispatchEventImpl(Unknown Source)
         at java.awt.Component.dispatchEvent(Unknown Source)
         at java.awt.EventQueue.dispatchEvent(Unknown Source)
         at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
         at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
         at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
         at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
         at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
         at java.awt.EventDispatchThread.run(Unknown Source)
    2011-04-01 11:58:17,504 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:36 - KEY1-keystroke [java.awt.DefaultKeyboardFocusManager@377369]: java.awt.event.KeyEvent[KEY_RELEASED,keyCode=27,keyText=Escape,keyChar=Escape,keyLocation=KEY_LOCATION_STANDARD,rawCode=27,primaryLevelUnicode=27,scancode=1] on javax.swing.JTextField[,320,28,175x18,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.ep.skin.lnf.framework.utils.internal.RoundedBorder@c3a7c0,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=15,columnWidth=11,command=,horizontalAlignment=LEADING]
    2011-04-01 11:58:17,506 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:42 - KEY2-ActiveWindow: javax.swing.JFrame[mainFrame,128,128,1024x768,invalid,layout=java.awt.BorderLayout,title=My - HQ - 17601,resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,1024x768,invalid,layout=com.ep.skin.lnf.framework.internal.RootPaneUI$MetalRootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource@d0e678,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
    2011-04-01 11:58:17,507 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:48 - KEY3-CurrentFocusCycleRoot: javax.swing.JFrame[mainFrame,128,128,1024x768,invalid,layout=java.awt.BorderLayout,title=My - HQ - 17601,resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,1024x768,invalid,layout=com.ep.skin.lnf.framework.internal.RootPaneUI$MetalRootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource@d0e678,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
    2011-04-01 11:58:17,508 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:54 - KEY4-FocusedWindow: javax.swing.JFrame[mainFrame,128,128,1024x768,invalid,layout=java.awt.BorderLayout,title=My - HQ - 17601,resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,1024x768,invalid,layout=com.ep.skin.lnf.framework.internal.RootPaneUI$MetalRootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource@d0e678,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
    2011-04-01 11:58:17,509 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:60 - KEY5-FocusOwner: javax.swing.JTextField[,320,28,175x18,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.ep.skin.lnf.framework.utils.internal.RoundedBorder@c3a7c0,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=15,columnWidth=11,command=,horizontalAlignment=LEADING]
    2011-04-01 11:58:17,510 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:66 - KEY6-PermanentFocusOwner: javax.swing.JTextField[,320,28,175x18,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.ep.skin.lnf.framework.utils.internal.RoundedBorder@c3a7c0,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=15,columnWidth=11,command=,horizontalAlignment=LEADING]
    2011-04-01 11:58:17,512 [AWT-EventQueue-1] DEBUG MyKeyEventDispatcher.dispatchKeyEvent:74 - KEY7-stacktrace...
    com..client.util.MyKeyEventDispatcher$StackTraceGenerationException: This exception was created to generate a stack trace, and can be safely ignored.
         at com..client.util.MyKeyEventDispatcher.dispatchKeyEvent(MyKeyEventDispatcher.java:73)
         at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
         at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
         at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
         at java.awt.Component.dispatchEventImpl(Unknown Source)
         at java.awt.Container.dispatchEventImpl(Unknown Source)
         at java.awt.Window.dispatchEventImpl(Unknown Source)
         at java.awt.Component.dispatchEvent(Unknown Source)
         at java.awt.EventQueue.dispatchEvent(Unknown Source)
         at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
         at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
         at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
         at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
         at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
         at java.awt.EventDispatchThread.run(Unknown Source)
    The above log info repeats multiple times, KEY_PRESSED and KEY_RELEASE, over and over again, for 'escape' keys.
    Edited by: 850693 on Apr 7, 2011 10:16 AM (typo fix)
    Edited by: 850693 on Apr 7, 2011 10:19 AM (Fixed links)

    <discaimer>Don't put too much hope in my reply</disclaimer>
    The only real difference is QA has the Citrix client installed on them, and development does not. You don't need to run our Swing app through a Citrix client though to cause the bug/freezing, just running it on a PC with the Citrix client seems to be enough (in theory). We've been working down a checklist of possible problems/solutions, and we've gotten to the "Install Citrix to the dev PC" item now, so I'll post back if that makes a difference or not in reproducing the problem.
    I've also had QA people actually come over to a dev PC, without the Citrix client, and try to reproduce the problem, and they have not been able to. There's 'something' about their environment vs. ours, but not sure how that would manifest itself as a AWT/Swing keyboard event of mysterious escape keystrokes followed by the locking up on the keyboard, but not the whole Swing app. My personal guess is the Citirix client installing funky Windows-level keyboard driver(s), but I may be totally off on that. /shrugI read your initial post twice and couldn't find out whether you reproduce that on several different machines, so one "environmental" difference comes to mind: have you tried using another keyboard on the defective QA configuration?
    Of course that doesn't explain in itself how the problem would manifest only after switching back and forth to a native Windows app, but then, with the hint that Citrix may make a difference, maybe one driver filters out repeated "Esc" keystrokes, while another doesn't, and that manifests only after a few app switches, and the system event queue, or whatever it's called in Windows, redirects the events to the target app/window?
    Other than that, I wish you had investigated Jeanette's pacemaker hypothesis more... ;)
    Otherwise, yeah. I have a hook in to see all AWTEvent's, but I still need to see/find what's posting the mysterious escape keys to the event queue.I assume it's what you mean, but I'll try to make that clear: you have to investigate, at the OS level, what is posting escape key events to the OS queue.
    I am not a Windows developper, but I seem to understand that the following programs claims to capture keystrokes on the whole screen (not limited to a single window), with some limitations: http://www.codeproject.com/KB/winsdk/WIN_RECORDER.aspx
    More generally, you should search for a Windows way to peek at the Windows' (keyboard?) event queue.
    I'm not sure this could identify which DLL (if it's not originated by the material, see the defective keyboard hypothesis) is posting the events, but that's worth a try (Java for example, would enables to stuff a custom event queue that would trace info about a Java-poster).
    Even if you can't identify the posting DLL, running the "key captuyre" on both the Windows host that has the Citrix window, and the Windows host that you are accessing via Citrix, may give you hints as to where the heck the key strokes originate...
    Good luck, and keep us informed,
    J.

  • Swing app in JDK6 continues to rendering slow in Windows Terminal Server

    Hi,
    Because Swing apps create interfaces internally and not using default OS APIs,
    when running into a Windows Terminal Server client, there is no way to optimize
    rendering. Windows Terminal Server and Linux FreeNX use a mechanism to send
    to client only commands to render the windows. But, because the way Swing works,
    not totally integrated to OS APIs, it's not possible for terminal servers to do this,
    and these servers render Swing like images, something like VNC do, very slower than.
    I have tested native apps and AWT apps, and the difference is very significant,
    something like 50-70% faster.
    Is there some project in Swing APIs or java.net open-sources to better this?

    We are also seeing this issue with a Compiere implementation. With 10 distributed sites across the US, our client wanted to use Windows Terminal Services to simplify the client desktop management of the Swing application.
    But performance is terrible...and screen painting issues a real problem. We are also on JDK5 still, so I'm discouraged to see that JDK6 doesn't appear to offer much improvement?
    Is there any project afoot to address this issue for installations using terminal services?
    Thanks,
    Peter

  • Applied an update to an app that records blood pressure. Am unable to retr ieve previously stored info. When following directions in update I cannot "add" data to import because message states data are stored elsewhere and I cannot find where. Help?

    Applied an update to an app that records blood pressure. Am unable to retrieve previously stored info. When following directions in update, I cannot "add" data to import because message states data are stored elsewhere, and I cannot find where. Help?

    You'll have to contact the app developer for help with this.

  • Best way to manage images in a swing app

    Hi.
    I have a swing app that uses alot of images around 100+ at around 40kb each.
    I am currently using new ImageIcon("icon\\main.png")) to create them.
    Is this the most efficient way to manage images?
    Would it be more efficeint to store then in the mysql database?
    and / or use SwingWorker (http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html)
    Cheers
    Bobby

    Hi Bobby,
    It depends on what you want to be more efficient:
    1) CPU cycles
    2) Reducing jar size
    3) Ease of maintenance
    4) Prevent typing errors in file names
    For me, number 3 and 4 are important. So, what I generally do, is create an enum that desribes the images that are contained in the same package as the enum. Now I'm able to change the package name with no consequence. I only have to type the filename once and know when I have to double check of what I type. Something like this:
    package org.pbjar.geom.images;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    public enum Images {
        AUTHOR_SMALL("TheAuthor.jpg"),
        AUTHOR_LARGE("PietKopLarge.jpg"),
        private final String filename;
        Images(String filename) {
         this.filename = filename;
        public ImageIcon getIcon() {
         return new ImageIcon(getImage());
        public BufferedImage getImage(){
         try {
             return ImageIO.read(getURL());
         } catch (IOException e) {
             throw new RuntimeException(e);
        public URL getURL() {
         return this.getClass().getResource(filename);
    }Piet

  • Expandable Menu in Java Swing app

    Hello JFriends,
    is it possible to create a expandable menu in java swing app? I am thinking of something like menu in MS Visio: http://img32.imageshack.us/i/menuip.jpg/
    It works like that: When user click on a bar it expands (with nice animation) and shows containing components.
    Or maybye there are components like that?
    Thanks in advance for Your reply and please forgive me if my english is bad.
    JRegards :-)

    Yes, such constructs are possible. There isn't a pre-made component exactly like that. The NetBeans IDE has a Window - named Palette - that's very similar. The code is open source.
    You can read about Java menus here:
    [http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html]

  • Is it possible to run my swing app in another jre

    Hi All,
    I have a swing app jar deployed in the server having jre. It may be possible that the client may have a lower version of jre. In that case would it be possible to download the jre itself from the server (local server not Sun server) and then the run the application in the downloaded jre. The client may be in windows or linux. Please give me steps to go about it. Am new to web start. Please help ASAP.
    Thanks to all the folks out there keeping the java community alive and kicking

    Hi Andy,
    I wanted to bring the jre on the client machine on par with the one in my server which hosts the application to be launched by web start. I had posted a query on how to install a newer version of jre other than using the sun's auto installer site. I had to search high and low for such a solution. Finally got a set of servlets called web start services from the following site :
    http://lopica.sourceforge.net/.
    It helped me to host the jre installer on my server itself which woulc be used by the client to install a higher version of jre if required. I was trying to install a runtime installer of jre as per their instructions. I created a jar file called jre_1.5.05.jar created by doing a jar -cvf on the jar directory. And gave the j2se version required as <j2se version="1.5.05"> and then my helloapp.jar. Everything goes fine during the installation. It also asks me for the reboot and I did the same. However when I try to run the application, it says
    "Bad Installation. Error involving Java VM (SysExec) and then points to the directtory inm the cache as .ext/E11332440658/bin/javaw.exe.
    So I went to the directory .ext/E11332440658 in the cache. and I see that the jar has been in jarred as jre_1.5.0_05/bin/javaws.exe which should have been the actual path where web start should have looked.
    Do you have any idea why it happened? Is it possible to correct it without doing anything manually at the client side? Please reply ASAP.
    Zeus.

  • How make Swing app Rotated 90 Deg? i.e. On its side

    I want to make my entire swing app (including buttons, JTextArea, etc) rotated 90 deg to the right. I know this sounds weird, but I want to do it for a PDA. I can use swing on a PDA (check on google for swing personal java) and I want to be able to have the screen the long width.
    Does anyone know how I can do this?

    I can suggest some solution but it has not been proved to work. So just read it and make your own component carefully.
    First, subclass the Swing-widget to be rotated and name it RButton or whatever.
    Then, draw the content on a new BufferedImage instance and use AffineTransform to draw this BufferedImage onto the original Graphics context. Here is the example code.public class RButton extends javax.swing.JButton {
      public void paintComponent( Graphics g ) {
        // 1. create a new BufferedImage to draw on.
        BufferedImage bi = new BufferedImage( this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB );
        // 2. draw the content (using JButton's paintComponent())
        super.paintComponent( bi.getGraphics() );
        // 3. save the old transformation matrix
        Graphics2D g2 = (Graphics2D)g;
        AffineTransform oldTransform = g2.getTransform();
        // 4. set the rotation transformation matrix
        g2.setTransform( AffineTransform.getRotateInstance( Math.toRadians( /*degree*/ ) ) );
        // 5. draw the BufferedImage on 'g'
        g2.drawImage( bi, 0, 0, this );
        // 6. reset the old transformation matrix
        g2.setTransform( oldTransform );
    }And this suggestion will just rotate the drawn content. You have to resize and rearrange those Rxxx components you've created to fit with the rotated graphics.

  • Why AWT apps are faster than Swing apps?

    I have written applications using both AWT and Swing. While running under Windows, I feel that AWT apps are much faster and smoother. In contrast, Swing apps fare terribly. Regardless, I can not go back to AWT because of thier limited capabilities.
    I love Java APIs, it is great for programmer. But what about the consumers? Consumers do not care whether it is written in Java or Visual C++?
    I am having a mid-"programming" crisis. I do not want to but, but would be forced to use VC++ for desktop apps abandoning Java.
    I would like to know if you are a serious desktop programmers, what is your motivation for using Java, not VC++ or something?
    Thanks.

    well, for me, it's that one it's Platform Independent. and that does come in handy when your work uses macs instead of normal PCs. Second, it's free to use, unlike VC++ and Pseudo Code (Visual Basic), you don't have to pay unbeleivably large sums of money to get a good compiler. And then there's the whole "Swings Apps are Slower", yes they are, however, if you program them write, they only take a while to initialize, once that is done they run as fast as any Native Program unless you have a tremendous amount of calculations and dynamic generation of components. And also the no Excecutables, true, and... not true, creating a Jar File is almost the same as making a making an EXE, only Jar Files are... platform independent.... and unlike C++ which gives you enough rope to run around the world three times, jump over the moon and hang yourself for actually using it, Java is a clean programming language, not a whole lot of those nasty characters and styles that ugly up your code. at least these are the reasons why i pick Java as the language to come out on top of all others.

  • Swing app can't connect to DB outside jDev

    I am using jDeveloper 11.1.1.3 and have create a simple swing app with a Model and View project that connects to DB. Everything runs fine inside the IDE but when i try to execute the program outside of jDeveloper i get a null password error when it tries to access my DB. I have created the connection in application resources and have checked the 'Save Password' option. I am executing the command from a .bat file, the same command jDev uses to launch the main form inside the IDE. The form displays and the buttons work but it will not connect.
    I tried to enter the password in the connections.xml file but the main form will not load if i do this.
    What am i missing here?
    Thanks a lot.
    Edited by: user10378872 on Feb 17, 2011 8:03 AM
    Edited by: user10378872 on Feb 17, 2011 8:03 AM
    Edited by: user10378872 on Feb 17, 2011 8:06 AM

    Hello !!
    He tenido problemas con PERSISTENCIA en NETBEANS 6.1 cuando trabajo en modo grafico. (Your same problem ! ).
    Hoy por fin lo pude solucionar. La solucion:
    En la clase principal que contine el metodo MAIN, en mi caso ContaApp.java busque el metodo " public static void main(String[] args) "
    en este metodo metodo se lanza la aplicacion en la linea:
    ESTAS 2 LINEAS SE DEBEN COLOCAR ANTES DE LANZA EL METODO launch( INDICADO MAS ABAJO.
    // This is the solution !!!
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("contabilidad");
    EntityManager em = emf.createEntityManager();
    // solution end
    // este es el metodo que se lanza autmaticamente (class method)
    launch(ContaDianApp.class, args);
    Y ESO ES TODO. TU PUEDES COLOCAR TU CONEXION NORMAL EN CUALQUIER PARTE DE TU CODIGO. ES IMPORTANTE VOLVER A INSTANCIAR LA PERSISTENCIA EN TU CODIGO. ES DECIR, QUE MAS ADELANTE NECESITAS VOLVER A COLOCAR:
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("contabilidad"); // contabilidad en mi caso, tu lo debes cambiar.
    EntityManager em = emf.createEntityManager();
    Cualquier inquietud te puedes comunicar conmigo al email: [email protected]
    saludos,
    Luis Carlos

Maybe you are looking for

  • Does HP Deskjet 1510 have e-print?

    Does HP Deskjet 1510 have e-print?

  • Strange Problem with File Content Conversion (Sender)

    Hi, I have a strange problem. I have a sender file adapter with content conversion (csv -> xml). The adapter produces the following error during the processing... - 2006-02-06 16:34:00 CET: Error: Conversion of part of file content of 'OE_Extractor_4

  • Can't locate page to "Add contacts"

    Pls help; can't locate the page to "add contacts".  email: [e-mail removed for privacy and security]

  • How do I view a saved web page?

    I saved a web page by clicking on File; Save Page as; and then saving it as a web page. This created a folder, which contained a large number of files, but when I try to open the folder, it simply opens the folder in Windows Explorer, and does not br

  • FM POSTING_INTERFACE_CLEARING for posting FB05

    Hi, In this FM, there is a table T_FTCLEAR I passed in 2 search parameters into T_FTCLEAR: BELNR = 12345 and GJAHR = 2011 However, when the BDC runs into this screen (SAPMF05A     0733), the default operation is OR Meaning, FB05 will search for docum