2011-08-31 11 views
6

Tôi đã dành thời gian đọc và thử nghiệm ở đây, và đưa ra một vài cách tiếp cận, nhưng không có bất kỳ cách nào để làm việc hoàn toàn, vì vậy tôi muốn biết những người lập trình Swing có kinh nghiệm hơn sẽ làm gì.Làm cách nào để phủ, thay đổi kích thước và căn giữa một thành phần trên JPanel?

Cửa sổ chính của ứng dụng của tôi chứa một loại phụ tùy chỉnh của JPanel, được sử dụng để hiển thị hình ảnh được tính từ một hàm toán học. Điều này có thể mất một thời gian để tính toán, vì vậy trong khi điều này xảy ra, tôi hiển thị một tin nhắn văn bản và một thanh tiến trình chồng lên ở giữa của bảng điều khiển. Tôi muốn cả hai văn bản và thanh tiến trình để thay đổi kích thước một cách thích hợp khi bảng điều khiển được thay đổi kích cỡ, có thể sử dụng một phần không đổi của chiều rộng của bảng điều khiển.

Hiện tại tôi có một loại phụ JPanel khác chứa văn bản và thanh tiến trình và tôi thêm "bảng tiến trình" này vào bảng điều khiển chính và đặt nó thành hiển thị khi được yêu cầu. Bảng điều khiển chính không chứa bất kỳ thành phần nào khác, nhưng có phương thức paintComponent() của riêng nó để hiển thị BufferedImage thu được từ một lớp khác. Có một số vấn đề với điều này vì nó là viết tắt:

  • Bảng tiến trình không phải lúc nào cũng hiển thị khi cần, có lẽ vì không có mã nào được bảo đảm rõ ràng ở phía trước hình ảnh.
  • Bảng tiến trình luôn chiếm toàn bộ chiều rộng của bảng điều khiển ứng dụng. Nó được căn giữa theo chiều dọc bằng cách sử dụng hộp thoại BoxLayout trong bảng chính với một số keo thẳng đứng trước và sau bảng tiến độ, nhưng tôi đã không có được cùng một thủ thuật để làm việc theo chiều ngang, và trong bất kỳ trường hợp nào không nhất thiết phải. Một cách tiếp cận gần như hoạt động là sử dụng BorderLayout với thanh ngang và dọc xung quanh bảng tiến độ, nhưng kích thước của bảng điều khiển tiến trình vẫn không đúng, và thanh chống cần được thay đổi khi bảng điều khiển chính được thay đổi kích thước.

Vậy bạn sẽ làm gì?

  • Sử dụng trình quản lý bố cục khác trong bảng điều khiển chính?
  • Sử dụng LayeredPane hoặc OverlayLayout bằng cách nào đó?
  • Thêm một lớp nữa vào hệ thống phân cấp chứa bảng điều khiển hình ảnh và bảng tiến trình?
  • Một số kết hợp ở trên hoặc thứ gì đó khác?

Điều gì về việc thay đổi kích thước văn bản. Tôi có cần phải tạo rõ ràng một Phông chữ mới khi bảng điều khiển được thay đổi kích thước hoặc có cách nào để thực hiện điều này tự động hơn không? -

+0

câu hỏi hay 1 – mKorbel

+0

IMHO nó không phải là điển hình để mở rộng kích thước phông chữ như các điều khiển trong một cửa sổ được thay đổi kích cỡ. Không nói nó nhất thiết phải là một ý tưởng tồi, nhưng điều này chắc chắn không được nướng vào Swing. Tuy nhiên, do tính đa dạng của các kích thước hiển thị, tôi đánh giá cao các giao diện người dùng cho phép kích thước văn bản được thay đổi một trình duyệt hiện đại. Vì vậy, nó có lẽ là một tính năng riêng biệt mà bạn có thể làm việc sau phần này: CTRL +/- để thay đổi kích thước phông chữ. –

Trả lời

2

Tôi biết đây là câu hỏi bố cục, nhưng SwingWorker có thể làm cho vấn đề trở nên đơn giản hơn nếu bạn có kết quả tạm thời hữu ích. Đôi khi tôi bắt đầu với điều này example.

+0

Cảm ơn. Tôi đã sử dụng một 'SwingWorker' để tính toán hình ảnh và thiết lập giá trị của thanh tiến trình. Tại một số điểm, tôi hy vọng sẽ hiển thị hình ảnh không đầy đủ khi nó được tạo ra. Đây chỉ là một dự án đồ chơi tôi đang sử dụng để cải thiện kiến ​​thức của tôi về Swing. – Ben

+0

Ví dụ hay. :-) – trashgod

3

Kích thước ưa thích của JProgressBar được chỉ định bởi đại biểu giao diện người dùng, BasicProgressBarUI. Ví dụ dưới đây minh họa hiệu quả của các trình quản lý bố cục khác nhau. FlowLayout chỉ cần sử dụng mặc định UIManager, ProgressBar.horizontalSize, trong khi GridLayoutBorderLayout.CENTER lấp đầy khoảng trống có sẵn. BoxLayout, với keo dán cạnh, điều chỉnh tỉ lệ khi khung được thay đổi kích thước.

Tôi đã sử dụng một SwingWorker

Cập nhật GUI từ phương pháp process() của bạn SwingWorker phải an toàn. Bạn có thể thay đổi các lớp hoặc thậm chí loại bỏ các thành phần, nhưng tôi sẽ cảnh giác với bất cứ điều gì quá phức tạp.

PreogressTest

Phụ lục: Đây là mặc định có liên quan.

System.out.println(UIManager.get("ProgressBar.horizontalSize")); 
 
javax.swing.plaf.DimensionUIResource[width=146,height=12] 

Code:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.GridLayout; 
import java.awt.LayoutManager; 
import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 

/** @see http://stackoverflow.com/questions/7256775 */ 
public class ProgressTest { 

    private static final Color border = Color.gray; 

    private static void display() { 
     JFrame f = new JFrame("ProgressTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new GridLayout(0, 1)); 
     f.add(createPanel(new FlowLayout())); 
     f.add(createPanel(new GridLayout())); 
     f.add(createPanel(new BorderLayout())); 

     JPanel p = new JPanel(); 
     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); 
     p.setBorder(BorderFactory.createLineBorder(border)); 
     JProgressBar jpb = new JProgressBar(); 
     p.add(Box.createHorizontalGlue()); 
     p.add(jpb); 
     p.add(Box.createHorizontalGlue()); 
     jpb.setIndeterminate(true); 
     f.add(p); 

     f.pack(); 
     f.setSize(320, 240); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    private static JPanel createPanel(LayoutManager layout) { 
     JPanel p = new JPanel(); 
     p.setBorder(BorderFactory.createLineBorder(border)); 
     p.setLayout(layout); 
     JProgressBar jpb = new JProgressBar(); 
     jpb.setIndeterminate(true); 
     p.add(jpb); 
     return p; 
    } 

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

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