Получение Java для отображения более 1.add()

#java #swing #user-interface #jframe #layout-manager

#java #swing #пользовательский интерфейс #jframe #макет-менеджер

Вопрос:

Я начал изучать базовый Java и хотел переписать генератор игровых карт, который я когда-то написал на PHP. У меня часть этого работает нормально (это только начало), но всякий раз, когда я хочу отобразить 2 вещи (используя .add()), он будет отображать только одну из них. Вот мой код;

 public static void main(String[] args) {
    JFrame m1 = new JFrame();
    Container con = m1.getContentPane();
    Color c = new Color(16, 174, 0);
    con.setBackground(c);
    m1.setSize(mapWidth, mapHeight);
    m1.setTitle("ThomasMosey's Map Generator"); // Window Title
    m1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    m1.add(new User());
    m1.add(new Grid());
    m1.setVisible(true);
}
  

Это только часть кода, но мне было интересно, не сделал ли я чего-нибудь не так с .add там.

Заранее благодарю вас.


Это полный код;

 import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Map extends JFrame {
    public static int mapWidth = 576; // The Map's Width
    public static int mapHeight = 598; // The Map's Height
    public static int userX = 1;
    public static int userY = 1;
    private static final long serialVersionUID = 1L;
    public static void main(String[] args) {
        JFrame m1 = new JFrame();
        Container con = m1.getContentPane();
        Color c = new Color(16, 174, 0);
        con.setBackground(c);
        m1.setSize(mapWidth, mapHeight);
        m1.setTitle("ThomasMosey's Map Generator"); // Window Title
        m1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        con.add(new User(), BorderLayout.NORTH);
        con.add(new Grid(), BorderLayout.CENTER);
        m1.setVisible(true);
    }
}
// The Grid system
class Grid extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g2.setColor(gridColor);
        int i;
        int i2;
        for(i = 50; i <= Map.mapWidth; i  = 51) {
            g2.drawLine(0, i, Map.mapWidth, i);
        }
        for(i2 = 50; i2 <= Map.mapHeight; i2  = 51) {
            g2.drawLine(i2, 0, i2, Map.mapHeight);
        }
    }
}
// Drawing the Grid but lower down to give a significant difference to check whether or not it's actually drawing on the JFrame
class User extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paint(Graphics g2) {
        Graphics2D g22 = (Graphics2D) g2;
        g22.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g22.setColor(gridColor);
        int i22;
        for(i22 = 50; i22 <= 6000; i22  = 53) {
            g22.drawLine(0, i22, Map.mapWidth, i22 1);
        }
    }
}
  

Комментарии:

1. «Это только часть кода ..» Для получения лучшей помощи раньше отправьте SSCCE . Если бы у вас было, я бы протестировал свой ответ, прежде чем публиковать его.

2. Я только что опубликовал свой полный код. Это не очень большой файл.

3. Это классический SSCCE. Смотрите мою правку для получения дополнительных советов.

Ответ №1:

  1. Макет по умолчанию для области содержимого BorderLayout .
  2. Добавьте компонент в макет границы без ограничений, и он окажется в CENTER .
  3. В каждой части макета границы может отображаться только один компонент.

Поэтому попробуйте это вместо этого..

 m1.add(new User(), BorderLayout.NORTH);
m1.add(new Grid(), BorderLayout.CENTER);
  

Часть проблемы заключается в том, что пользовательские компоненты имеют предпочтительный размер по умолчанию 0x0. Попробуйте этот вариант.

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

public class Map extends JFrame {
    public static int mapWidth = 576; // The Map's Width
    public static int mapHeight = 598; // The Map's Height
    public static int userX = 1;
    public static int userY = 1;
    private static final long serialVersionUID = 1L;
    public static void main(String[] args) {
        JFrame m1 = new JFrame();
        Container con = m1.getContentPane();
        Color c = new Color(16, 174, 0);
        con.setBackground(c);
        // bad form - pack() instead
        //m1.setSize(mapWidth, mapHeight);
        m1.setTitle("ThomasMosey's Map Generator"); // Window Title
        m1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        User user = new User();
        user.setPreferredSize(new Dimension(300,300));
        con.add(user, BorderLayout.NORTH);
        Grid grid = new Grid();
        grid.setPreferredSize(new Dimension(600,600));
        con.add(grid, BorderLayout.CENTER);
        m1.pack();
        m1.setVisible(true);
    }
}
// The Grid system
class Grid extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g2.setColor(gridColor);
        int i;
        int i2;
        for(i = 50; i <= Map.mapWidth; i  = 51) {
            g2.drawLine(0, i, Map.mapWidth, i);
        }
        for(i2 = 50; i2 <= Map.mapHeight; i2  = 51) {
            g2.drawLine(i2, 0, i2, Map.mapHeight);
        }
    }
}
// Drawing the Grid but lower down to give a significant difference to check whether or not it's actually drawing on the JFrame
class User extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paintComponent(Graphics g2) {
        Graphics2D g22 = (Graphics2D) g2;
        g22.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g22.setColor(gridColor);
        int i22;
        for(i22 = 50; i22 <= 6000; i22  = 53) {
            g22.drawLine(0, i22, Map.mapWidth, i22 1);
        }
    }
}
  

Комментарии:

1. Добавление BorderLayout. РАЗБИВКА по ЦЕНТРУ и границе. PAGE_START это не меняет. РЕДАКТИРОВАТЬ: ваше второе исправление не сработало.

2. Это сработало, но я хотел, чтобы они накладывались друг на друга. Есть ли способ сделать это?

3. Что, Grid и User ? Здесь пользователь действительно появляется «поверх» Grid . Вы имели в виду, что они должны быть многоуровневыми? Что пользователь прозрачен, и вы можете видеть сетку за ним?

4. Да — это то, что я хочу, если это возможно. Извините, что не даю достаточно подробностей.

5. Хаха, спасибо за вашу помощь! Я постараюсь сделать все это одним классом. Еще раз спасибо.

Ответ №2:

Текущая компоновка JFrame является BorderLayout , и вы добавляете оба этих компонента в центр. Попробуйте изменить макет.

 Container con = m1.getContentPane();
con.setLayout(new FlowLayout());
  

или

 m1.add(new User(),BorderLayout.NORTH);
m1.add(new Grid(),BorderLayout.CENTER);
  

РЕДАКТИРОВАТЬ: вы должны переопределить метод setPreferredSize() для пользователя.

 class User extends JComponent {
  public java.awt.Dimension getPreferredSize() { 
    return new java.awt.Dimension(100,100);
  }
}
  

Комментарии:

1. Спасибо за повторную установку вашего ответа. Я был готов проголосовать еще до получения совета о предпочтительном размере. (Хотя я не согласен с тем, что лучше переопределить метод, но это скорее вопрос дизайна.)

Ответ №3:

AFAIR, панель содержимого, поддерживающая JFrame, по умолчанию принимает только одного дочернего элемента. Вам нужно будет установить и настроить некоторый макет, чтобы иметь более одного дочернего элемента

Комментарии:

1. -1 Панель содержимого a JFrame может принимать 5 компонентов без изменения макета.