2015-09-12 23 views
7

Tôi có nguồn gây bực mình này được viết để minh họa bố cục cho màn hình trò chơi được đề cập trên another question. Nó đặt các nút (hoặc nhãn, có thể chọn lúc khởi động) vào một số GridBagLayout.Xóa khoảng trống xung quanh các nút trong GridBagLayout

Nếu bạn chọn không sử dụng các nút khi được nhắc (trước khi GUI xuất hiện) toàn bộ GUI đẹp và nhỏ gọn mà không có khoảng trống. Nhưng nếu bạn chọn để sử dụng các nút nó sẽ (nếu thiết lập của mình cũng giống như mỏ) trông giống như thế này ..

enter image description here

Lưu ý các đường ngang màu đỏ. Đó là màu BG của bảng hiển thị thông qua. Những dòng này không được nhìn thấy khi GUI sử dụng các nhãn. Kéo dài GUI một chút để thấy rằng nó thậm chí không đặt một đường màu đỏ sau mỗi hàng (có chín hàng) - mặc dù mỗi hàng sử dụng các nút (cùng các thành phần).

Làm cách nào để xóa không gian dọc phụ khi sử dụng nút?

Tôi nghĩ rằng đó phải là điều tôi quên làm khi định cấu hình các nút hoặc trọng số hàng, nhưng tôi không thể hiểu được điều gì!

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

import java.net.URL; 
import javax.imageio.ImageIO; 

public class SoccerField { 

    private JPanel ui = null; 
    int[] x = {0, 35, 70, 107, 142, 177, 212, 247, 282, 315}; 
    int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345}; 
    boolean buttons; 

    SoccerField() { 
     initUI(); 
    } 

    public void initUI() { 
     int result = JOptionPane.showConfirmDialog(ui, "Use buttons?"); 
     buttons = result == JOptionPane.OK_OPTION; 
     if (ui != null) { 
      return; 
     } 

     ui = new JPanel(new GridBagLayout()); 
     ui.setBackground(Color.RED); 

     try { 
      URL url = new URL("http://i.stack.imgur.com/9E5ky.jpg"); 
      BufferedImage img = ImageIO.read(url); 
      BufferedImage field = img.getSubimage(100, 350, 315, 345); 

      BufferedImage[] bi = subSampleImageColumns(field); 
      BufferedImage[][] fieldParts = new BufferedImage[bi.length][]; 
      for (int ii=0; ii<bi.length; ii++) { 
       fieldParts[ii] = subSampleImageRows(bi[ii]); 
      } 
      for (int ii=0; ii<fieldParts[0].length; ii++) { 
       for (int jj=0; jj<fieldParts.length; jj++) { 
        addImageToPanel(ui, fieldParts[ii][jj], ii, jj); 
       } 
      } 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private void addImageToPanel(JPanel panel, BufferedImage img, int row, int col) { 
     Insets insets = new Insets(0,0,0,0); 
     GridBagConstraints gbc = new GridBagConstraints(
       row, col, 
       1, 1, 
       .5, .5, 
       GridBagConstraints.CENTER, 
       GridBagConstraints.BOTH, 
       insets, 0, 0); 
     ImageIcon ii = new ImageIcon(img); 
     JButton b = new JButton(ii); 
     b.setBorder(null); 
     b.setBorderPainted(false); 
     b.setContentAreaFilled(false); 
     Component c = buttons ? b : new JLabel(ii); 
     panel.add(c, gbc); 
    } 

    private BufferedImage[] subSampleImageColumns(BufferedImage img) { 
     System.out.println("Image Size: " + img.getWidth() + "," + img.getHeight()); 
     BufferedImage[] imageRows = new BufferedImage[x.length - 1]; 
     for (int ii = 0; ii < x.length - 1; ii++) { 
      BufferedImage bi = img.getSubimage(
        x[ii], 0, x[ii + 1] - x[ii], img.getHeight()); 
      imageRows[ii] = bi; 
     } 

     return imageRows; 
    } 

    private BufferedImage[] subSampleImageRows(BufferedImage img) { 
     BufferedImage[] imageRows = new BufferedImage[y.length - 1]; 
     for (int ii = 0; ii < y.length - 1; ii++) { 
      BufferedImage bi = img.getSubimage(
        0, y[ii], img.getWidth(), y[ii + 1] - y[ii]); 
      imageRows[ii] = bi; 
     } 

     return imageRows; 
    } 

    public JComponent getUI() { 
     return ui; 
    } 

    public static void main(String[] args) { 
     Runnable r = new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (Exception useDefault) { 
       } 
       SoccerField o = new SoccerField(); 

       JFrame f = new JFrame(o.getClass().getSimpleName()); 
       f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       f.setLocationByPlatform(true); 

       f.setContentPane(o.getUI()); 
       f.pack(); 
       //f.setMinimumSize(f.getSize()); 

       f.setVisible(true); 
      } 
     }; 
     SwingUtilities.invokeLater(r); 
    } 
} 
+1

Câu hỏi ngu ngốc: bạn đã thử chỉ định 'EmptyBorder' (có insets 0 cho tất cả 4 giá trị) thay vì' null' khi đặt đường viền của nút chưa? Nó có thay đổi gì không? – Laf

+0

@Laf Không, nó không phải là một câu hỏi ngu ngốc và có tôi chắc chắn có. Hiệu ứng tương tự. Lý do duy nhất tôi đã không cung cấp một biến thể đó là laziness lúc thêm các chức năng (như trái ngược với chỉ thay đổi một dòng mã và biên dịch lại) và sau đó chọn một hay khác mỗi khi nó chạy. ;) –

+1

@Laf Như một bên, mã đó ** là ** hoàn toàn tự chứa, vì vậy nó phải được khá dễ dàng cho mọi người để chạy. Nó kéo hình ảnh trực tiếp từ imgur tại thời gian chạy. –

Trả lời

6

Nhận thấy rằng chiều cao ưa thích của các nút dường như không được tính toán chính xác cho các nút (trong một số trường hợp).

Trong trường hợp chiều cao của nhãn là 40, chiều cao của nút là 41.

của nó như nút sẽ luôn luôn thay đổi kích thước là một số lẻ?

tôi đã thay đổi mã:

//int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345}; 
int[] y = {0, 45, 86, 139, 180, 225, 266, 279, 320, 345}; 

và có vẻ như để làm việc.

Ah, vừa tìm ra lý do. Bạn cũng cần:

b.setFocusPainted(false); 
+1

* ".. và nó có vẻ hoạt động. Ah, chỉ tìm ra lý do" * Vâng, đúng vậy. Rực rỡ! –

Các vấn đề liên quan