2010-08-19 30 views
5

Câu hỏi của tôi tóm tắt điều này: đó là cấu trúc tiêu chuẩn trong lập trình Swing để cung cấp cho người nghe quyền kiểm soát các thành phần mới (ví dụ: JPanel mới) để hiển thị và nhập liệu, và để cho người nghe thành phần mới kiểm soát các thành phần mới để hiển thị và nhập liệu, và vân vân đến vô cùng? Hay Java cần phải hoàn nguyên về một loại lớp thống nhất nào đó liên kết tất cả các thành phần Swing với nhau theo một thứ tự thủ tục? Hiện tại, trong ứng dụng của tôi chỉ sử dụng một JFrame, trong trình lắng nghe của tôi, đối tượng JFrame ban đầu của tôi đang được chuyển thành tham số cho tất cả các JPanels của tôi để người nghe có thể gọi removeeall() để xóa khung cho JPanel mới . Ví dụ: mã ngắn như sauCấu trúc lập trình Java Swing: người nghe có phải là nguồn gốc của hầu hết các thành phần Swing không?

public class MainFrame { 
    JFrame jfrm; 
    public MainFrame() { 
    jfrm = new JFrame("Main Frame"); 
    JPanel mainPanel = new MainPanel(jfrm); 
    } 
} 

public class MainPanel extends JPanel { 
    public MainPanel(final JFrame mainFrame) { 
    JButton example = new JButton("Example"); 
    example.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent le) { 
      mainFrame.removeall(); 
      JPanel 2ndPanel = new 2ndPanel(mainFrame); 
      mainFrame.add(2ndPanel); 
      mainFrame.validate(); 
     } 
    }); 
    } 
} 

Đây có phải là cấu trúc đúng - nơi mà người nghe tạo bảng mới chứ không phải một số lớp thống nhất? Nhưng nếu đó là trường hợp, làm thế nào để trình biên dịch Java bao giờ nhận được để mainFrame.validate() nếu có một tầng vô cùng của người nghe? Tôi là một lập trình viên thủ tục của trường cũ đang cố gắng lập trình một ứng dụng Swing trong Java, và tôi nghĩ rằng tôi có thể không nắm bắt được các khái niệm cơ bản về lập trình Swing. Rất mong nhận được bất kỳ câu trả lời hữu ích nào và cảm ơn trước!

+0

Mục đích của JButton của bạn là gì? Nếu nó thực sự loại bỏ tất cả từ JFrame, và đặt một số JPanel mới ở đó? – amorfis

+0

@amorfis: Cảm ơn nhận xét. Về bản chất, mục đích của JButton là gửi một tín hiệu mà người dùng đã chọn các tùy chọn khác nhau trong một JPanel và muốn tiếp tục tới màn hình tiếp theo. Có lẽ nó nên được JButton ("Next") để cung cấp cho bạn một số ý tưởng. – Arvanem

Trả lời

4

Tôi sẽ không làm như vậy. Mẫu quan sát được sử dụng trong Swing để gửi thông báo, thường là kết quả của hành động của người dùng.

Lấy ví dụ của bạn: Người dùng 'nhấp vào' trên nút vì anh ấy muốn một bảng điều khiển mới trong MainFrame. Nhưng nút không biết phải làm gì với một cú nhấp chuột. Tất cả những gì anh ấy có thể làm là thông báo cho người nghe sự kiện rằng họ đã được chọn.

Vì vậy, chúng tôi cần một số thành phần quan tâm đến thông báo. Thành phần này có thể đăng ký người nghe bằng nút và nhận thông báo. Người nghe là tai của các thành phần khác (hoặc là 'mắt'). Nhưng một tai (hoặc mắt) sẽ không hành động. Nó chỉ là cảm biến thành phần khác.

Điều này đưa chúng ta trở lại câu hỏi chính: người muốn được thông báo, nếu nút được nhấp và người phải thực hiện hành động. Đây là một câu hỏi thiết kế chính. Chắc chắn là không phải là người nghe tạo và thêm bảng điều khiển vào khung chính. Nó có thể là vai trò khung chính để tạo và thêm các bảng phụ hoặc vai trò của một thành phần thứ ba, chịu trách nhiệm tạo khung với các bảng phụ.

Nhưng người nghe là một nơi không tốt cho mã này.

+0

+1 cho cuộc thảo luận thông minh.Tôi sẽ đọc lên trên mẫu Observer và cố gắng giải quyết câu hỏi thiết kế mà bạn đặt ra - "ai muốn được thông báo"! Rất cám ơn vì đã gây nhiều suy nghĩ. – Arvanem

1

Trước hết bạn không nên để người nghe thao tác trực tiếp khung, sử dụng một lồng nhau JPanel hoặc là ContentPane.

Câu hỏi của bạn tùy thuộc vào vị trí người nghe của bạn. Bạn chỉ nên thêm các thành phần vào một số JFrame từ chính lớp đó. Trong trường hợp của bạn là OK, vì logic được giới hạn trong chính lớp đó.

Tôi không nghĩ rằng có vô số người nghe. Chúng nằm trong danh sách và được thực thi tuần tự. Người nghe của bạn nên sử dụng SwingUtilities.invokeLater để thao tác với khung chính.

Tôi thấy việc chuyển giao đối số JFrame làm đối số dư thừa một chút. Tại sao không tạo ra người nghe từ bên ngoài constructor?

final JPanel mainPanel = new MainPanel();  
JButton example = new JButton("Example"); 
example.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent le) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       MainFrame.this.removeAll(); 
       MainFrame.this.add(mainPanel); 
      } 
     });; 
    } 
}); 
add(example); 

Đây không phải là ví dụ hay nhất, nhưng tôi lưu ý rằng bạn đang cố gắng làm gì.

Điểm mấu chốt là bạn nên tạo các thành phần bên ngoài trình nghe, sau đó thêm nó bằng cách sử dụng trình nghe.

+0

+1 và cảm ơn bạn vì lời khuyên thiết thực. Tôi đồng ý một vô cực là một cường điệu. Đó là một câu hỏi khái niệm mà tôi đang hỏi. – Arvanem

3

Thay vì hủy và tạo bảng, bạn có thể muốn ẩn/hiển thị chúng. Có một trình quản lý bố cục CardLayout có thể thực hiện việc này: http://journals.ecs.soton.ac.uk/java/tutorial/ui/layout/card.html

Về cơ bản ý tưởng là tạo và thêm tất cả các bảng của bạn khi bắt đầu chương trình, sau đó sử dụng trình quản lý bố cục để lật giữa các chế độ xem.

Như đã nói bởi những người khác, bạn có thể muốn thêm một số loại mô hình vào thiết kế của mình, chịu trách nhiệm duy trì trạng thái của hệ thống.

+0

+1 và cảm ơn bạn đã cung cấp tùy chọn này. Tôi sẽ xem xét nó, nhưng cuối cùng tôi cần nắm bắt các khái niệm trước khi sử dụng cách dễ dàng. – Arvanem

1

Có một số nhầm lẫn theo cách, không bình thường, cách bạn đã tổ chức mã của mình. Như một quy tắc chung của Java, không phân lớp nơi bạn không có lý do. Nó hiếm khi có ý nghĩa với phân lớp JPanel hoặc JFrame.

Nó cũng hiếm khi có ý nghĩa để gán các thành phần cho các trường trong lớp tạo ra chúng. Trong thực tế, làm ít hơn trong các nhà xây dựng.

Cũng làm ít hơn trong các lớp bên trong vô danh. Detangle dữ liệu sự kiện và gọi một phương thức có ý nghĩa cho class kèm theo để có một hoạt động.

+0

+1 và cảm ơn lời khuyên của bạn. Nó không phải là dễ dàng để làm theo hướng dẫn của bạn mà không có lợi ích của mã mẫu nhưng tôi sẽ cố gắng để thực hiện các quy định này. – Arvanem

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