Качели струны централизованные - PullRequest
0 голосов
/ 17 мая 2019

Я должен нарисовать n + 1 количество кругов по горизонтали и вертикали в графическом интерфейсе.Что я успешно сделал, как показано ниже.При этом между ними будет напечатан двумерный массив строк, централизованный.

Как это в настоящее время стоит

enter image description here

Теперь я хочурисовать числа в «квадрате» точек.

Как мне нужен конечный результат

enter image description here

for (int i = 0; i < width; i++) {
    for (int j = 0; j < width; j++) {
        canvas.drawCircle( (j + 1) * 125, (i + 1) * 125, 15, Color.white);
    }
}

for (int r = 0; r < size; r++) {
    for (int c = 0; c < size; c++) {
        canvas.drawString(events[r][c], (r + 1) * 150, (c + 1) * 150, Color.green );
    }
}

Ширина вэтот случай равен 4, поэтому в основном (n-1) точек / кружков на рисунке.

Размер равен 3, что является только длиной массива 2d, так как в этом случае будет 4 круга, будет 3числа между каждым

События - это двумерный массив с данными, содержащими числа

Подпись метода drawCircle (x, y, radius, color)

Метод drawStringПодпись (текст, x, y цвет)

Я считаю, что частью проблемы также является рисование кругов.По сути, я думаю, что это связано с формулой мусора, которую я имею для определения координат x, y как для окружностей, так и для текста.Спасибо за любую помощь, спасибо.

Ответы [ 3 ]

0 голосов
/ 17 мая 2019

Рассмотрим класс, представляющий один квадрат.Значение представлено JLabel, который помещается внизу, используя прямой менеджер компоновки (BorderLayout в этом примере).Вы можете изменить или манипулировать менеджером по расположению, чтобы изменить положение JLabel.

class Square extends JPanel{

    private static int WIDTH = 100, HEIGHT = 100, DAIMETER  = 30, GAP = 5;
    private final JLabel label;

    Square(int value) {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setLayout(new BorderLayout());
        setBackground(Color.red);
        setOpaque(true);
        label = new JLabel(String.valueOf(value), JLabel.RIGHT);
        label.setForeground (Color.white);
        Border margin = new EmptyBorder(GAP,GAP,GAP,2*GAP); //top left bottom right
        label.setBorder(margin);
        add(label, BorderLayout.PAGE_END);
    }

    @Override
    public void paintComponent(Graphics g){

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.white);
        g2d.fillOval(WIDTH/2 - DAIMETER/2, HEIGHT/2-DAIMETER/2, DAIMETER, DAIMETER);
    }
}

Теперь добавьте 16 экземпляров этого Square на панель, представляющую доску.Его менеджер компоновки имеет значение GridLayout:

class Board extends JPanel{

    private static int ROWS = 4, COLS = 4;

    Board(){
        setLayout(new GridLayout(ROWS, COLS));

        for(int index = 0; index < ROWS * COLS; index ++){
            add(new Square(index)); //index is used as value for demonstration purposes 
        }
    }
}

Собирает все вместе (это mcve с одним файлом. Скопируйте, вставьте весь код в SwingMain.java и запустите)

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

public class SwingMain {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(400,250);
        frame.add(new Board());
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
    }
}

class Board extends JPanel{

    private static int ROWS = 4, COLS = 4;

    Board(){
        setLayout(new GridLayout(ROWS, COLS));

        for(int index = 0; index < ROWS * COLS; index ++){
            add(new Square(index)); //index is used as value for demonstration purposes 
        }
    }
}

class Square extends JPanel{

    private static int WIDTH = 100, HEIGHT = 100, DAIMETER  = 30, GAP = 5;
    private final JLabel label;

    Square(int value) {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setLayout(new BorderLayout());
        setBackground(Color.red);
        setOpaque(true);
        label = new JLabel(String.valueOf(value), JLabel.RIGHT);
        label.setForeground (Color.white);
        Border margin = new EmptyBorder(GAP,GAP,GAP,2*GAP); //top left bottom right
        label.setBorder(margin);
        add(label, BorderLayout.PAGE_END);
    }

    @Override
    public void paintComponent(Graphics g){

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.white);
        g2d.fillOval(WIDTH/2 - DAIMETER/2, HEIGHT/2-DAIMETER/2, DAIMETER, DAIMETER);
    }
}

enter image description here

0 голосов
/ 18 мая 2019

Предоставлен некоторый код, который, я считаю, делает то, что вы хотите. Некоторые из констант могут быть настроены в соответствии с вашими конечными требованиями. Я использовал двумерный массив чисел и преобразовал его в строки во время рисования. Это также позволяет:

  • Изменение диаметра или количества шариков все равно обеспечит правильный график (хотя он изменит свое местоположение в пределах панель).
  • Трек чисел String вместе с размером шариков
  • Сглаживание включено, чтобы сгладить графику.
  • FontMetrics был использован для точной настройки местоположения чисел.

Последнее замечание: поскольку это не требует значительных ресурсов, координаты рассчитываются в методе paintComponent. Более оптимальным решением было бы принять Flyweight design pattern и максимально рассчитать его перед вводом paintComponent.


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

    public class SwingMain extends JPanel {

       final static int WIDTH      = 700;
       final static int HEIGHT     = 700;
       final static int SEPARATION = 100;
       final static int DIAMETER   = 25;
       final static int NBALLS     = 4;
       final static int XSTART     = WIDTH / (NBALLS + 2);
       final static int YSTART     = HEIGHT / (NBALLS + 2);
       JFrame           frame      = new JFrame();
       int[][]          numbers    = new int[NBALLS - 1][NBALLS - 1];

       public static void main(String[] args) {
          SwingUtilities.invokeLater(() -> new SwingMain().start());
       }

       public void start() {
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          setPreferredSize(new Dimension(WIDTH, HEIGHT));
          frame.add(this);
          setBackground(Color.RED);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
          // populate numbers in 2D array.
          for (int r = 0; r < NBALLS - 1; r++) {
             for (int c = 0; c < NBALLS - 1; c++) {
                numbers[r][c] = r * (NBALLS - 1) + c + 1;
             }
          }
       }

       @Override
       public void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2d = (Graphics2D) g;

          // Allow smoothing of the graphics.
          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
          g2d.setColor(Color.white);

          // Iterating by the number of balls is more consistent than
          // by x and y due to round of errors.

          int y = YSTART;
          for (int r = 0; r < NBALLS; r++) {
             int x = XSTART;
             for (int c = 0; c < NBALLS; c++) {
                g2d.fillOval(x, y, DIAMETER, DIAMETER);
                x += SEPARATION;
             }
             y += SEPARATION;
          }

          // This is the same as above except that the start begins
          // halfway between the first row and column

          // have the size of the font track with the diameter of the balls
          g2d.setFont(new Font("ARIAL", Font.BOLD, DIAMETER));
          FontMetrics fm = g2d.getFontMetrics();
          y = YSTART + SEPARATION / 2;
          for (int r = 0; r < NBALLS - 1; r++) {
             int x = XSTART + SEPARATION / 2;
             for (int c = 0; c < NBALLS - 1; c++) {
                String number = Integer.toString(numbers[r][c]);

                // Do some final position adjustment with the font metrics to
                // center the number

                int strWidth = fm.stringWidth(number);
                int strHeight = fm.getAscent();
                g2d.drawString(number,
                      x - strWidth / 2 + DIAMETER / 2,
                      y + strHeight);

                x += SEPARATION;
             }
             y += SEPARATION;
          }

       }

    }

0 голосов
/ 17 мая 2019

Вы также можете хранить координаты окружностей в двумерном массиве и использовать это, чтобы найти расположение строк. Следует отметить, что метод drawCircle по какой-то причине не будет рисовать окружность с заданным центром (координаты, которые вы дадите, будут фактически верхним левым углом).

Point[][] circleCoords = new Point[width][width]; //suppose Point class has x and y coords 

for (int i = 0; i < width; i++) {
   for (int j = 0; j < width; j++) {
    //the -15 actually centers the circle to the coordianates
    circleCoords[i][j] = new Point((j + 1) * 125 - 15, (i + 1) * 125 -15);
    canvas.drawCircle(circleCoords[i][j].x , circleCoords[i][j].y, 15, Color.white);
   }
}

for (int r = 0; r < width-1; r++) {
   for (int c = 0; c < width-1; c++) {
    //calculate coords from circleCoords array: halfway between them
    int xCoord = (circleCoords[r][c].x + circleCoords[r+1][c].x)/2; 
    int yCoord = (circleCoords[r][c].y + circleCoords[r][c+1].y)/2;
    //wont be out of bounds, becouse this runs to width-1
    canvas.drawString(events[r][c], xCoord, yCoord, Color.green );
    }
 }

Это все еще не будет идеально отцентрировано, потому что drawString будет использовать координаты для верхней левой точки, а не центральной точки. Возможно, я что-то просчитал, но это должно дать вам идею: вместо того, чтобы вычислять координаты независимо, повторно используйте координаты круга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...