2012-07-19 35 views
6

Tôi đang cố tải cùng một hình ảnh được lưu trữ nhãn hai lần vào bảng điều khiển lưới, tuy nhiên thay vì tạo hai trường hợp của hình ảnh, hình ảnh chỉ được hiển thị một lần sau đó được di chuyển.Hình ảnh JLabel mảng

Làm cách nào để lưu trữ cùng một vị trí JLabel trong mảng miếng vào nhiều hơn một JLabel trong mảng bảng tính.

Cảm ơn :)

public static JPanel boardPanel = new JPanel(new GridLayout(4, 0)); 
public static JLabel pieces[] = new JLabel[2]; 
private static JLabel[] boardLabels = new JLabel[4]; 

public MainFrame() { 
    pieces[0] = new JLabel(new ImageIcon(System.getProperty("user.dir") + "/images/piece1.png")); 
    pieces[1] = new JLabel(new ImageIcon(System.getProperty("user.dir") + "/images/piece2.png")); 

    this.add(boardPanel); 
    displayGUIboard(); 
} 


public static void displayGUIboard() { 

    //ERROR - the label in pieces[0] is not copied into both boardLabels [0] and [1] 
    boardLabels[0] = pieces[0]; 
    boardLabels[1] = pieces[0]; 

    boardPanel.add(boardLabels[0]); 
    boardPanel.add(boardLabels[1]); 
} 

public static void main(String[] args) { 
    MainFrame frame = new MainFrame(); 
    frame.setVisible(true); 
    frame.setSize(600, 600); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

này hoạt động

boardLabels[0] = new JLabel(pieces[1]); 
    boardLabels[1] = new JLabel(pieces[1]); 

khi sử dụng ImageIcons, nhưng tôi muốn tránh điều này kể từ khi cập nhật bảng tôi sẽ phải gỡ bỏ sau đó tải lại JLabels. Tôi muốn chỉ cập nhật các nhãn đã được tải.

chỉnh sửa Tôi cố gắng này trước đây nhưng nó ném một con trỏ ngoại lệ null ...

boardLabels[0].setIcon(pieces[1]); 
    boardLabels[1].setIcon(pieces[1]); 

    boardPanel.add(boardLabels[0]); 
    boardPanel.add(boardLabels[1]); 
+2

Đạt được một tài nguyên ứng dụng từ một đường dẫn tương đối đến 'user.dir' là *** rất *** mong manh. Vì những hình ảnh này rõ ràng là vốn có của ứng dụng., Chúng nên được thêm vào Jar làm [tài nguyên nhúng] (http://stackoverflow.com/tags/embedded-resource/info). –

Trả lời

9

Đừng làm điều này kể từ khi bạn không thể thêm các thành phần tương tự nhiều hơn một lần một container hình dung. Tốt hơn nên sử dụng nhiều JLabels nhưng để chúng sử dụng cùng một số ImageIcon. ImageIcons thể được sử dụng nhiều hơn một lần một cách dễ dàng:

public MainFrame() { 
    pieceIcon[0] = new ImageIcon(System.getProperty("user.dir") + 
     "/images/piece1.png"); 
    pieceIcon[1] = new ImageIcon(System.getProperty("user.dir") + 
     "/images/piece2.png"); 

    this.add(boardPanel); 
    displayGUIboard(); 
} 


public void displayGUIboard() { 
    boardPanel.add(new JLabel(pieceIcon[0]); 
    boardPanel.add(new JLabel(pieceIcon[0]); 
} 

Là một sang một bên: lưu ý rằng none các biến của bạn nên tĩnh.

Edit: liên quan đến chỉnh sửa gần đây của bạn:

này hoạt động

boardLabels[0] = new JLabel(pieces[1]); 
boardLabels[1] = new JLabel(pieces[1]); 

khi sử dụng ImageIcons, nhưng tôi muốn tránh điều này kể từ khi cập nhật bảng tôi sẽ có để xóa rồi tải lại các JLabels. Tôi muốn chỉ cần cập nhật các nhãn đã nạp."

Giải pháp
Không bạn không cần phải thay đổi JLabels ở tất cả. Giữ JLabels của bạn, nơi họ đang có, nhưng chỉ đơn giản là trao đổi các biểu tượng mà họ nắm giữ sử dụng phương pháp JLabel setIcon(...).

Sửa
Ngoài ra, không nhầm lẫn giữa các biến với các đối tượng. Thậm chí nếu bạn tạo ra một loạt các biến JLabel, nếu tất cả họ đều tham khảo các đối tượng JLabel cùng, bạn vẫn có thể không thêm một đối tượng JLabel JLabel nhiều lần một thùng chứa.

Sửa Bạn trạng:

Mã này là một phần của chức năng hiển thị cho một trò chơi.Một mảng các số nguyên sẽ đại diện cho hội đồng quản trị được diễn giải (nhưng không phải trong đoạn mã trên) và các hình ảnh chính xác của Jlabel sẽ được đặt vào một bảng điều khiển lưới để hiển thị gui của bảng. Tôi đã nhận được mã hiển thị để làm việc tốt, nhưng trong phiên bản hiện tại của tôi nó loại bỏ các jlabels từ hội đồng quản trị sau đó tạo mới JLabels (piece ...) ... nhưng tôi muốn nó để cập nhật chính nó từ mảng số nguyên chứ không phải loại bỏ các nhãn, đọc mảng, sau đó tạo lại các nhãn.

Vì vậy, tạo một JPanel sử dụng GridLayout và điền nó với JLabels không thay đổi. Sau đó, chỉ cần thay đổi các biểu tượng được giữ bởi các JLabels dựa trên các giá trị được giữ bởi mảng int. Bạn có thể tạo một phương thức đơn giản hóa và tự động hóa quá trình này.

Sửa về:

chỉnh sửa tôi đã cố gắng này trước đây nhưng nó ném một con trỏ ngoại lệ null.

Sau đó, giải quyết điều này giống như bạn làm bất kỳ NPE nào. Tìm ra dòng nào ném NPE, kiểm tra các biến trên dòng, ít nhất một là null, và sau đó sửa chữa nó để bạn khởi tạo biến trước khi cố gắng sử dụng nó.

Sửa
ví dụ:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import java.awt.image.BufferedImage; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class GridExample extends JPanel { 
    public static final int[][] MAP = { 
     {1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2}, 
     {1, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2}, 
     {1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2}, 
     {1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2}, 
     {1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2}, 
     {1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2}, 
     {1, 1, 0, 0, 0, 2, 2, 2, 2, 2, 2}, 
     {1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2}, 
     {1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2}, 
     {1, 1, 1, 1, 1, 0, 0, 0, 2, 2, 2}, 
     {1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 2} 
    }; 

    public static final Color[] COLORS = {}; 
    private JLabel[][] labelGrid = new JLabel[MAP.length][MAP[0].length]; 

    public GridExample() { 
     setLayout(new GridLayout(MAP.length, MAP[0].length)); 
     for (int r = 0; r < labelGrid.length; r++) { 
     for (int c = 0; c < labelGrid[r].length; c++) { 
      labelGrid[r][c] = new JLabel(); 
      labelGrid[r][c].setIcon(Ground.getGround(MAP[r][c]).getIcon()); 
      add(labelGrid[r][c]);    
     } 
     } 
    } 

    private static void createAndShowGui() { 
     GridExample mainPanel = new GridExample(); 

     JFrame frame = new JFrame("GridExample"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

enum Ground { 
    DIRT(0, new Color(205,133, 63)), GRASS(1, new Color(0, 107, 60)), 
    WATER(2, new Color(29, 172, 214)); 
    private int value; 
    private Color color; 
    private Icon icon; 

    private Ground(int value, Color color) { 
     this.value = value; 
     this.color = color; 

     icon = createIcon(color); 
    } 

    private Icon createIcon(Color color) { 
     int width = 24; // how to use const in enum? 
     BufferedImage img = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB); 
     Graphics g = img.getGraphics(); 
     g.setColor(color); 
     g.fillRect(0, 0, width, width); 
     g.dispose(); 
     return new ImageIcon(img); 
    } 

    public int getValue() { 
     return value; 
    } 

    public Color getColor() { 
     return color; 
    } 

    public Icon getIcon() { 
     return icon; 
    } 

    public static Ground getGround(int value) { 
     for (Ground ground : Ground.values()) { 
     if (ground.getValue() == value) { 
      return ground; 
     } 
     } 
     return null; 
    } 

} 

nào cho thấy một mạng lưới GUI:
enter image description here

+0

Tôi đã tạo nhiều JLabels trong mảng boardLabel, nhưng chúng không được gán với cùng một JLabel từ mảng mảnh vì các mẫu Jlabels trong mảng mảnh không thể được thêm hai lần, đúng không? – user1334130

+0

Ha ha! đăng cùng một điều – user1334130

+0

Vì vậy, nó sẽ không thể cập nhật một số lượng thiết lập của JLabels vì tất cả đều trỏ đến cùng một đối tượng mà không hoạt động. – user1334130

10

Để so sánh, tôi đã tái yếu tố @ HFOE của example để Ground implements Icon và lập chỉ mục các mảng được trả về bởi values(). Vì value là chi tiết triển khai, thay vào đó, int[][] MAP có thể là Ground[][] MAP.

Cập nhật: Biến thể này minh họa Ground[][] MAP và thêm TexturePaint.

enter image description here

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.TexturePaint; 
import java.awt.geom.Rectangle2D; 
import java.awt.image.BufferedImage; 
import java.util.Random; 
import javax.swing.*; 

/** @see https://stackoverflow.com/a/11556441/230513 */ 
public class GridExample extends JPanel { 

    public static final Ground[][] MAP = { 
     {Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.WATER, Ground.WATER}, 
     {Ground.GRASS, Ground.DIRT, Ground.CITY, Ground.WATER, Ground.WATER}, 
     {Ground.GRASS, Ground.DIRT, Ground.CITY, Ground.WATER, Ground.WATER}, 
     {Ground.GRASS, Ground.DIRT, Ground.DIRT, Ground.DIRT, Ground.WATER}, 
     {Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.WATER, Ground.WATER}, 
    }; 
    private JLabel[][] labelGrid = new JLabel[MAP.length][MAP[0].length]; 

    public GridExample() { 
     setLayout(new GridLayout(MAP.length, MAP[0].length)); 
     for (int r = 0; r < labelGrid.length; r++) { 
      for (int c = 0; c < labelGrid[r].length; c++) { 
       labelGrid[r][c] = new JLabel(); 
       labelGrid[r][c].setIcon(MAP[r][c]); 
       add(labelGrid[r][c]); 
      } 
     } 
    } 

    private static void createAndShowGui() { 
     GridExample mainPanel = new GridExample(); 
     JFrame frame = new JFrame("GridExample"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowGui(); 
      } 
     }); 
    } 
} 

enum Ground implements Icon { 

    DIRT(new Color(205, 133, 63)), GRASS(new Color(0, 107, 60)), 
    WATER(new Color(29, 172, 214)), CITY(Color.lightGray); 
    private static final int SIZE = 42; 
    private Random random = new Random(); 
    private TexturePaint paint; 

    private Ground(Color color) { 
     this.paint = initPaint(color); 
    } 

    private TexturePaint initPaint(Color color) { 
     BufferedImage image = new BufferedImage(
      SIZE, SIZE, BufferedImage.TYPE_INT_ARGB); 
     Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, SIZE, SIZE); 
     for (int row = 0; row < SIZE; row++) { 
      for (int col = 0; col < SIZE; col++) { 
       if (random.nextBoolean()) { 
        image.setRGB(col, row, color.getRGB()); 
       } else { 
        if (random.nextBoolean()) { 
         image.setRGB(col, row, color.darker().getRGB()); 
        } else { 
         image.setRGB(col, row, color.brighter().getRGB()); 
        } 
       } 
      } 
     } 
     return new TexturePaint(image, rect); 
    } 

    @Override 
    public void paintIcon(Component c, Graphics g, int x, int y) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setPaint(paint); 
     g.fillRect(0, 0, SIZE, SIZE); 
    } 

    @Override 
    public int getIconWidth() { 
     return SIZE; 
    } 

    @Override 
    public int getIconHeight() { 
     return SIZE; 
    } 
} 
Các vấn đề liên quan