Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Нарисовать листочек в клеточку


Автор: Qawra 20.12.2008, 13:22
для  школы нам надо за каникулы написать игру используя GUI . За три занятия нам это GUI обьяснили но практических навыков у меня нет .А надо изобразить листочек в клеточку где два игрока по очереди ставят точки а компьютер обводит замкнутые контуры одного цвета .
Что-то подобное есть  здесь но оно не на Java
http://www.yoursdots.narod.ru/

Я нарисовала как смогла простое окошко 

Код

import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class  MyGui extends JFrame 
    {
    private JPanel main,south,north,center;

    private JButton sizeButton  ;
    
    
    public MyGui(String title)  // constractor which would be used to create MainWindow
    {   super (title);  // super means that we use constractor from  parent  JFrame class 
        build();
    }
    private void build()
     {
        north = new JPanel(new FlowLayout(FlowLayout.LEFT));
        south = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        center = new JPanel(new FlowLayout(FlowLayout.LEFT));
        
        main = new JPanel(new BorderLayout());
        
        this.add(main);
        main.add(south,BorderLayout.SOUTH);
        main.add(north,BorderLayout.NORTH);
        main.add(center,BorderLayout.CENTER);
        
        
        //this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setDefaultCloseOperation(HIDE_ON_CLOSE);
        this.setSize(1000,800);
        this.setResizable(false);
        this.setVisible(true);
        
        
    }
    
    
  }



Надо нарисавать на нём решётку.
Читаю   сейчас по английски на 
http://math.hws.edu/javamath/javadoc/edu/hws/jcm/draw/Grid.html
public class Grid
extends Drawable

A Grid object draws a graph paper-like grid on a Canvas. The pixel width and height between adjacent grid lines is specified as a parameter to the constructer, or through the access methods "setXSP(double)" and "setYSP(double)". Note that the spacing will be scaled to between PIX_MIN and PIX_MAX (20 and 80, respectively, by default). The color of the grid lines can be set, and defaults to (220, 220, 220).


Кажется это то что мне надо.
Но не понятно с конструктором после того  как я изменю 
public class  MyGui extends JFrame , implementsDrawable

я должна передать в конструктор размеры ячейки .А конструктор мне кажется вообще ничего общего с Grid or Drawable не имеет ! Как это можно обойти ?


Автор: dorogoyIV 20.12.2008, 13:38
не очень давно я писал здесь в тему про шашки (правда там не доделано, но у меня есть доделанная версия).
поищи поиском

Автор: Qawra 20.12.2008, 13:42
не получается даже 
public class  MyGui extends JFrame implements Drawable

я импортировала на всякий случай дополнительно 
import java.lang.Object ;
но BlueJ всё равно пишет cann't find symbol (по видимому имея в виду Drawable).

Автор: Qawra 20.12.2008, 14:06
хорошие шашки.. иногда правда они меня не слушаются . Наверное искусственный интеллект !  
Клетки хорошо прорисованы но мне ведь нужна только клеточная сетка и  с той целью что-бы потом в её углах рисовать точки .Я вот теперь думаю.. А как определять что это угол клетки и там можно поставить точку в процессе игры ? Это же целая проблема вырисовывается ...

Автор: Cyclone 20.12.2008, 14:36
Цитата(Qawra @ 20.12.2008,  14:06)
Я вот теперь думаю.. А как определять что это угол клетки и там можно поставить точку в процессе игры ? Это же целая проблема вырисовывается ...

У тебя клетки будут определённого размера. По координатам клика мыши ты сможешь понять, на пересечении он произведён, или нет.
Ставишь на свою панельку gridPanel.addMouseListener(..); .
В обработчике события mouseClicked(..) проверяешь координаты клика, получая их из входного объекта события ("MouseEvent e", по-моему).

Условно говоря, размер клетки: 10*10px. Если e.getX(); делится на 10 без остатка, значит клик был совершён на вертикальной линии. То же самое для горизонтальной - по координате Y.
Лучше, конечно, небольшой "зазор" для клика оставить, чтобы не приходилось целиться в уголок с точностью до пикселя.
Например, остаток от деления < 3 или > 7.

 smile 

Автор: Qawra 20.12.2008, 14:59
Понятно... как только изображу решетку  сразу попытаюсь применить ..Надо implements  все три 
MouseListener,ChangeListener, FocusListener  ?

Автор: SoulKeeper 20.12.2008, 20:08
Код

import javax.swing.*;
import java.awt.*;

public class GridPanel extends JPanel {

    private int rows;

    private int columns;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        int rowStep = getHeight() / rows;
        int columnStep = getWidth() / columns;

        for(int i = 1; i < rows; i++){
            int y = i * rowStep;
            g.drawLine(0, y, getWidth(), y);
        }

        for(int i = 1; i < columnStep; i++){
            int x = i * columnStep;
            g.drawLine(x, 0, x, getHeight());
        }
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public int getColumns() {
        return columns;
    }

    public void setColumns(int columns) {
        this.columns = columns;
    }
}


Решетка ;)

Автор: Qawra 20.12.2008, 22:01
спасибо... это её надо попробовать в моё окно на центральную панель прикрепить ..А в ней нет конструктора ....Сейчас попробую наубум его нарисовать smile
Не получается  .. 
.

Автор: SoulKeeper 21.12.2008, 00:42
Код


import javax.swing.*;
import java.awt.*;

public class GridTest extends JFrame{

    public GridTest() throws HeadlessException {
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        GridPanel panel = new GridPanel();
        panel.setRows(20);
        panel.setColumns(20);

        panel.setPreferredSize(new Dimension(800, 800));
        add(new JScrollPane(panel));
        pack();
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                GridTest gridTest = new GridTest();
                gridTest.setVisible(true);
            }
        });
    }
}

Автор: Qawra 21.12.2008, 10:28
А у меня этот код вывел пустое окошко без решётки :(
Надо где-то изобразить что-то вроде
  ....getGraphics().drawLine(x,y,x+20,y+20);
Но где теперь это изобразить !

Автор: Qawra 21.12.2008, 11:17
Когда я пытаюсь включить это в метод build 
программа говорит что         for (int i=0 ; i<1000;i+20) is not a statement .
что ей не нравится ?
Код

private void build()
     {
        north = new JPanel(new FlowLayout(FlowLayout.LEFT));
        south = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        center = new JPanel(new FlowLayout(FlowLayout.LEFT));
        
        main = new JPanel(new BorderLayout());
        
        this.add(main);
        main.add(south,BorderLayout.SOUTH);
        main.add(north,BorderLayout.NORTH);
        main.add(center,BorderLayout.CENTER);
        
        
        //this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setDefaultCloseOperation(HIDE_ON_CLOSE);
        this.setSize(1000,1000);
        this.setResizable(false);
        
                           // trying to draw a grid
                     for (int i=0 ; i<1000;i+20)
        { for(int j=0;j<1000;j+20)
            {center.getGraphics().drawLine(x,y,x+20,y+20)
              }
          }
        
        this.setVisible(true);
            
    }

Может ей конечно ещё что-то не нравится но пока она об этом не говорит .Я например не уверенна что (x,y,x+20,y+20) позволит нарисовать  именно решётку smile 
Методов getWight  и getHeigth  у меня не было прописанно потому что окно не было resizable  , его ширина и высота шли как  постоянные .Может быть конечно это лучше переделать .

Автор: Qawra 21.12.2008, 20:00
решёточку я изобразила так 
Код

import java.awt.Canvas;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends Canvas 
{
  int width, height;
  int rows;
  int cols;

  GridsCanvas(int w, int h, int r, int c) 
  {
    setSize(width = w, height = h);
    rows = r;
    cols = c;
  }

  public void paint(Graphics g) 
  {
    int i;
    width = getSize().width;
    height = getSize().height;

    // draw the rows
    int rowHt = height / (rows);
    for (i = 0; i < rows; i++)
      g.drawLine(0, i * rowHt, width, i * rowHt);

    // draw the columns
    int rowWid = width / (cols);
    for (i = 0; i < cols; i++)
      g.drawLine(i * rowWid, 0, i * rowWid, height);
  }
}

public class Grids extends Frame 
{
  
  Grids(String title, int w, int h, int rows, int cols) // constractor
  {
    setTitle(title);

    // Now create a Canvas and add it to the Frame.
    GridsCanvas canvas = new GridsCanvas(w, h, rows, cols);
    
    add(canvas);

    addWindowListener(new WindowAdapter() 
    {
      public void windowClosing(WindowEvent e)
      {
        setVisible(false);
        setResizable(false);
        dispose();
        System.exit(0);
      }
    });

    pack();
  }

  public static void main(String[] a) {
    new Grids("BattleGraund", 800, 800, 30, 30).setVisible(true);
  }
}


Я хотела сделать её постоянного размера  
setResizable(false);
что бы потом по координатам можно было определить где можно ставить точку ( углы клеток )
А в  реальности решётка  получилась Resizable !
Почему ?!

Автор: SoulKeeper 21.12.2008, 23:08
Не ресайзится. 

+ при выходе из приложения совершенно не надо делать setVisible(false), dispose, прочее.
Да и совершенно бессмысленно держать копию высоты и ширины, в общем чуть почистил.

Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends Canvas {

    int rows;
    int cols;

    GridsCanvas(int r, int c) {
        rows = r;
        cols = c;
    }

    public void paint(Graphics g) {
        int i;
        int width = getSize().width;
        int height = getSize().height;
        // draw the rows
        int rowHt = height / (rows);
        for (i = 0; i < rows; i++)
            g.drawLine(0, i * rowHt, width, i * rowHt);
        // draw the columns
        int rowWid = width / (cols);
        for (i = 0; i < cols; i++)
            g.drawLine(i * rowWid, 0, i * rowWid, height);
    }


}

public class Grids extends Frame {

    Grids(String title, int w, int h, int rows, int cols) // constractor
    {
        setTitle(title);
        // Now create a Canvas and add it to the Frame.
        GridsCanvas canvas = new GridsCanvas(rows, cols);
        canvas.setSize(w, h);

        add(canvas);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Exit " + getTitle() + "?", "Confirm exit", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.OK_OPTION) {
                    System.exit(0);
                }
            }
        });
        pack();

        //Set this windown in the center
        setLocationRelativeTo(null);

        // Set it not resizable
        setResizable(false);
    }

    public static void main(String[] a) {
        new Grids("BattleGraund", 800, 800, 30, 30).setVisible(true);
    }
}



P.S.
Почему AWT а не Swing?

P.P.S.
Не стоит экономить пару строчек кода делая его трудно читаемым.
Код

setSize(width = w, height = h);


P.P.P.S
Цитата

А у меня этот код вывел пустое окошко без решётки :(

Как это без? У меня же с решеткой smile

Автор: Qawra 22.12.2008, 15:16
Спасибо вам за такую чудненькую нерастягивающую решётку smile

У меня наверно BlueJ самовольничает. Кстати это бывает не редко . И в школе у нас тоже самое случается .Всё написано правильно - а он придирается. Сегодня он вашу решётку запускать вообще отказался потому что 
в строке 
public GridTest() throws HeadlessException 
он вдруг нашёл  " invalid method declaration " 
которого вчера там небыло .Вчера ошибок он не находил..
но и решётки там тоже  небыло ..

"Не стоит экономить пару строчек кода делая его трудно читаемым."

 Так я  же просто не знаю других вариантов .. 
Это был единственный вариант который я знала .
Ситуация похожа на обучение иностранному языку когда тебе просто дали  словарь и попросили  сразу написать стихи     на этом  языке . 
Это не момент творчества .Это момент кошмара ...

Мне вдруг пришла в голову мысль ..main метод при создании решётки надо отключить ..наверное ..
Если я помню правильно , в программе должен быть только один main метод ..А программа у меня начинает работать с 
другого окошка . Там игроки должны будут выбрать себе цвет чернил , затем нажать кнопку Start что бы появилась решётка где они будут  ставить свои точки..
Окошко у меня правда ещё совсем простецкое ..даже  без кнопки " Start" , но  main method  я уже там прописала ...
Код

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.Object ;
import java.io.Serializable;
import java.awt.Graphics;

public class  MyGui extends JFrame implements Serializable
    {
     private JPanel main,south,north,center;
     
    public MyGui(String title)  // constractor which would be used to create MainWindow
    {   super (title);  // super means that we use constractor from  parent  JFrame class 
        build();
    }
    private void build()
     {
        north = new JPanel(new FlowLayout(FlowLayout.LEFT));
        south = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        center = new JPanel(new FlowLayout(FlowLayout.LEFT));
        
        main = new JPanel(new BorderLayout());
        
        this.add(main);
        main.add(south,BorderLayout.SOUTH);
        main.add(north,BorderLayout.NORTH);
        main.add(center,BorderLayout.CENTER);
        
        
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setDefaultCloseOperation(HIDE_ON_CLOSE);
        this.setSize(600,600);
        this.setResizable(false);
        this.setVisible(true);
            
    }
    
}
public class MainWindow
{ public static void main (String args[])
  {
    MyGui window  = new MyGui (" Paper BattleGround  v 1"); // we pass the title of the new window to the constractor

  }
}


Импортировала я   наверно  всё что смогла  вспомнить  потому что  не  была  уверена что import javax.swing.*; 
предполагает  импорт всех дочерних библиотек  swing .





Автор: SoulKeeper 22.12.2008, 16:03
Цитата(Qawra @  22.12.2008,  15:16 Найти цитируемый пост)
Спасибо вам за такую чудненькую нерастягивающую решётку

Всегда рад smile

Цитата(Qawra @  22.12.2008,  15:16 Найти цитируемый пост)
 Так я  же просто не знаю других вариантов .. 
Это был единственный вариант который я знала .
Ситуация похожа на обучение иностранному языку когда тебе просто дали  словарь и попросили  сразу написать стихи     на этом  языке . 
Это не момент творчества .Это момент кошмара ...


Имелось ввиду что вместо

Код

setSize(width = w, height = h);


лутше писать

Код

width = w;
height = h;
setSize(width, height);



Цитата(Qawra @  22.12.2008,  15:16 Найти цитируемый пост)
У меня наверно BlueJ самовольничает. Кстати это бывает не редко

http://www.netbeans.org/
http://www.eclipse.org/
http://www.jetbrains.com/idea/index.html

Зачем себя мучить то smile?

Автор: Qawra 22.12.2008, 17:40

BlueJ , как учёба - дело принудительное  smile
Я бы с удовольствием интерфейс нарисовала в NetBeans 
да преподаватель не велел ...

Автор: Cyclone 25.12.2008, 17:22
Ну, ручками тоже надо уметь...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)