主頁 > 企業開發 > 如何使GridOverlay中的所有影像齊平?

如何使GridOverlay中的所有影像齊平?

2021-12-11 20:32:19 企業開發

我正在嘗試為我創建的滿足以下特定條件的基于迷宮的游戲實作 GUI:

  1. GUI 本身有一個固定的大小并且不可調整大小(第 41 行)。

  2. 包含所有迷宮影像的主面板(第 57 行)是可滾動的。所有迷宮影像組件彼此齊平。

    • 如果迷宮足夠小,則整個迷宮將在主面板中可見。
    • 如果迷宮非常大,則用戶需要滾動。
  3. 主面板需要由滑鼠偵聽器(第 130 行)訪問,該偵聽器回傳正在單擊的組件。

以下代碼似乎符合條件 1 和 3,但不符合條件 2:


public class MazeGui extends JFrame implements DungeonView {
  
  private final Board board;
  
  public MazeGui(ReadOnlyModel m) {

    
    //this.setSize(m.getNumRows()*100, m.getNumCols()*100);
    this.setSize(600, 600);
    this.setLocation(200, 200);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);

    this.board = new Board(m);
    JScrollPane scroller = new JScrollPane(board);
    this.add(scroller, BorderLayout.CENTER);

    setTitle("Dungeon Escape");

  }
  
  private class Board extends JPanel {

    private ReadOnlyModel m;
    

    public Board(ReadOnlyModel m) {

      this.m = m;
      GridLayout layout = new GridLayout(m.getNumRows(),m.getNumCols(), 0, 0);
//      layout.setHgap(-100);
//      layout.setVgap(-100);
      this.setLayout(layout);
      
      this.setSize(m.getNumRows()*64,m.getNumCols()*64);
      

      for (int i = 0; i < m.getNumRows() * m.getNumCols(); i  ) {
      
      try {
        // load resource from the classpath instead of a specific file location
        InputStream imageStream = getClass().getResourceAsStream(String.format("/images/%s.png", m.getRoomDirections(i   1)));
        // convert the input stream into an image
        Image image = ImageIO.read(imageStream);
        // add the image to a label
        JLabel label = new JLabel(new ImageIcon(image));
        label.setPreferredSize(new Dimension(64, 64));
        
        
        JPanel panel = new JPanel();
        panel.setSize(64, 64);
        String name = String.format("%d", i);
        panel.setName(name);
        panel.add(label);

        // add the label to the JFrame
        //this.layout.addLayoutComponent(TOOL_TIP_TEXT_KEY, label);

        
        this.add(panel);
        
      } catch (IOException e) {
        JOptionPane.showMessageDialog(this, e.getMessage());
        e.printStackTrace();
      }
    }


    }
  }
  
  

  @Override
  public void addClickListener(DungeonController listener) {

    Board board = this.board;
    
    MouseListener mouseListener = new MouseAdapter() {

      @Override
      public void mouseClicked(MouseEvent e) {

         System.out.println(String.format("(%d,%d)", e.getX(), e.getY()));
         JPanel panel = (JPanel) board.getComponentAt(e.getPoint());
         System.out.println(panel.getName());
         

      }

    };

    board.addMouseListener(mouseListener);

  }
    
  

  @Override
  public void refresh() {
    
    this.repaint();
  }

  @Override
  public void makeVisible() {

    this.setVisible(true);
    
  }

}

這是它產生的影像:

如何使Grid Overlay中的所有影像齊平?

uj5u.com熱心網友回復:

首先,我會使用不同的布局管理器,它會嘗試擴展以適應底層容器的大小。

然后,我會讓組件完成它們的作業。我不知道你為什么要將標簽添加到另一個面板,該面板似乎沒有添加額外的功能/特性,只是增加了復雜性。

如何使Grid Overlay中的所有影像齊平?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                List<Maze.Direction> directions = new ArrayList<>(32);
                directions.add(Maze.Direction.EAST_SOUTH);
                directions.add(Maze.Direction.EAST_SOUTH_WEST);
                directions.add(Maze.Direction.EAST_SOUTH_WEST);
                directions.add(Maze.Direction.EAST_SOUTH_WEST);
                directions.add(Maze.Direction.EAST_SOUTH_WEST);
                directions.add(Maze.Direction.SOUTH_WEST);
                directions.add(Maze.Direction.NORTH_EAST_SOUTH);
                directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
                directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
                directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
                directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
                directions.add(Maze.Direction.NORTH_SOUTH_WEST);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH_SOUTH);
                directions.add(Maze.Direction.NORTH);
                directions.add(Maze.Direction.NORTH);
                directions.add(Maze.Direction.NORTH);
                directions.add(Maze.Direction.NORTH);
                directions.add(Maze.Direction.NORTH);
                directions.add(Maze.Direction.NORTH);

                System.out.println(directions.size());

                Maze maze = new DefaultMaze(5, 6, directions);

                MazeGui frame = new MazeGui(maze);
                frame.addClickListener(null);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface Maze {

        enum Direction {
            EAST_SOUTH("EastSouth.png"), EAST_SOUTH_WEST("EastSouthWest.png"), SOUTH_WEST("SouthWest.png"),
            NORTH_EAST_SOUTH("NorthEastSouth.png"), NORTH_EAST_SOUTH_WEST("NorthEastSouthWest.png"),
            NORTH_SOUTH_WEST("NorthSouthWest.png"), NORTH_SOUTH("NorthSouth.png"), NORTH("North.png");

            private BufferedImage image;

            private Direction(String name) {
                try {
                    image = ImageIO.read(getClass().getResource("/images/"   name));
                } catch (IOException ex) {
                    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            public BufferedImage getImage() {
                return image;
            }

        }

        public int getRows();

        public int getColumns();

        public Direction getRoomDirections(int index);
    }

    public class DefaultMaze implements Maze {

        int rows;
        int columns;

        private List<Direction> directions;

        public DefaultMaze(int rows, int columns, List<Direction> directions) {
            this.rows = rows;
            this.columns = columns;
            this.directions = directions;
        }

        public int getRows() {
            return rows;
        }

        public int getColumns() {
            return columns;
        }

        @Override
        public Direction getRoomDirections(int index) {
            return directions.get(index);
        }
    }

    public class MazeGui extends JFrame {

        // Missing code
        public interface DungeonController {
        }

        private final Board board;

        public MazeGui(Maze m) {
            this.setSize(600, 600);
            this.setResizable(false);

            this.board = new Board(m);
            JScrollPane scroller = new JScrollPane(board);
            this.add(scroller, BorderLayout.CENTER);

            setTitle("Dungeon Escape");
        }

        public Board getBoard() {
            return board;
        }

        public void addClickListener(DungeonController listener) {
            Board board = getBoard();
            board.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    Component cell = board.getComponentAt(e.getPoint());
                    System.out.println(cell.getName());
                    board.highlight(cell.getBounds());
                }
            });
        }

        private class Board extends JPanel {

            private Rectangle selectedCell;

            private Maze maze;

            public Board(Maze maze) {
                this.maze = maze;
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;

                for (int index = 0; index < maze.getRows() * maze.getColumns(); index  ) {
                    Maze.Direction direction = maze.getRoomDirections(index);
                    JLabel label = new JLabel(new ImageIcon(direction.getImage()));
                    label.setName(direction.name());
                    add(label, gbc);
                    gbc.gridx  ;
                    if (gbc.gridx >= maze.getColumns()) {
                        gbc.gridx = 0;
                        gbc.gridy  ;
                    }
                }

//                addMouseListener(new MouseAdapter() {
//                    @Override
//                    public void mouseClicked(MouseEvent e) {
//                        Component component = getComponentAt(e.getPoint());
//                        selectedCell = null;
//                        if (component != null) {
//                            selectedCell = component.getBounds();
//                        }
//                        repaint();
//                    }
//                });
            }

            public void highlight(Rectangle bounds) {
                selectedCell = bounds;
                repaint();
            }

            @Override
            public void paint(Graphics g) {
                super.paint(g);
                if (selectedCell != null) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    g2d.setColor(new Color(0, 0, 255, 128));
                    g2d.fill(selectedCell);
                    g2d.dispose();
                }
            }
        }
    }
}

uj5u.com熱心網友回復:

GUI 本身具有固定大小且不可調整大小

所以這里的問題是你強制“板”面板具有任意大小。

this.setSize(600, 600);

面板的實際大小應該是 8 * 64 = 512。因此每個網格都添加了額外的空間。

不要硬編碼大小值。

布局管理器的作業是確定每個組件的首選大小。

因此,不要使用 setSize(...) ,而是pack()在使其可見之前應該使用框架:

this.pack();
this.setVisible(true);

當你這樣做時,你會看到迷宮完全適合框架。

如果你想要迷宮周圍的額外空間,那么你需要在你的板上添加一個“邊框”:

setBorder( new EmptyBorder(88, 88, 88, 88) );
GridLayout layout = new GridLayout(m.getNumRows(),m.getNumCols(), 0, 0);

原來我應該一直在使用 GridBagLayout!

無需更改布局管理器,只需更有效地使用布局管理器即可。

如果您確實出于某種原因需要指定固定的幀大小,那么您可以進行以下更改:

//this.add(scroller, BorderLayout.CENTER);
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(scroller, new GridBagConstraints());
this.add(wrapper, BorderLayout.CENTER);

這將允許“板”面板以其首選大小顯示,并且“板”面板將在其父容器中居中。

使用這些技巧將幫助您有效地創建更復雜的布局。

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/379360.html

標籤:爪哇 摇摆 框架 面板

上一篇:在第一次滑鼠點擊和游標之間顯示一條線

下一篇:如何根據我的paintComponent中的if條件在我的JavaGUI中繪制文本?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more