2013-11-07 9 views
-1

Еще одна проблема, та же программа:Закрепление латентность в Java

Ниже 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; 
    } 
} 

Ниже 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; 
     } 
    } 

} 

Ниже 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); 
    } 

} 

Таким образом, проблема сейчас, когда кнопка Randomize нажата или большое количество ячеек существует, а затем таймер запускается, клетки не так быстро, как они будут с менее активными клетками , Например, при 100 столбцах и 50 строках, когда нажата кнопка рандомизации, активируется одна ячейка, затем следующая, затем другая и так далее. Могу ли я активировать их в одно и то же время? Это просто проблема со слишком многими вещами, рассчитанными сразу? Помогло ли совмещение?

QUICK EDIT: Является ли таймер качания лучшей идеей для этого проекта?

+2

У вас * действительно * надеюсь, что кто-то будет читать через весь этот код? –

+0

Не совсем, но на всякий случай кто-то хотел задать вопрос об этом, тогда он был легко доступен. – mistapaluza

+0

Аналогичная проблема рассматривается [здесь] (http://stackoverflow.com/q/18933986/230513). – trashgod

ответ

0

Я полностью не прочитал ваш код , но Я предполагаю, что ваши методы слушателя достаточно интенсивно вычислительны и, следовательно, отставание в обновлении дисплея.

0

Этот простой тест показывает, что ваша операция Randomize должна быть достаточно быстро:

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"); 
} 

Выход для меня:

17580267ns/17ms 

Так что это заставляет меня думать, activate() или deactivate() вызывает ваш пользовательский интерфейс перерисовываться.


Я не могу работать, потому что я не ваши графические ресурсы, но я хотел бы попробовать эти изменения, чтобы увидеть, если он работает:

В MainGUI#actionPerformed, изменение:

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(); 
     } 
    } 
} 

к:

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(); 
} 

Добавить это 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; 

И изменение:

protected void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    if(getPosX()==MainGUI.columns-1&&getPosY()==0) 
    { 
     //do nothing 
    } 

к:

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 
    } 
Смежные вопросы