cuốn sách gpt4 ai đã làm

swing - Yêu cầu chiều cao của thành phần Swing không hợp lệ

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-03 04:56:55 30 4
mua khóa gpt4 Nike

Thiết lập cơ bản là thế này: Tôi có một JSplitPane dọc và tôi muốn nó có thành phần dưới cùng có kích thước cố định và thành phần trên cùng đã được thay đổi kích thước, tôi thực hiện bằng cách gọi setResizeWeight(1.0) để hoàn thành. Trong ứng dụng này có một nút để khôi phục cấu hình cửa sổ "mặc định". Chiều cao mặc định của cửa sổ là chiều cao của màn hình và vị trí dải phân cách mặc định là 100 pixel tính từ đáy của Ngăn được chia.

Để đặt vị trí dải phân cách thành 100px, tôi đặt chiều cao của JSplitPane thành - 100. Vấn đề là, ngay trước đó tôi đã thay đổi kích thước JFrame và vì mã nằm trong nút gọi lại nên JSplitPane bị vô hiệu hóa nhưng chưa được thay đổi kích thước. Vì vậy, vị trí dấu phân cách được đặt không chính xác.

Đây là SSCCE. Nhấp vào nút hai lần để xem vấn đề. Nhấp chuột đầu tiên sẽ thay đổi kích thước cửa sổ, nhưng vị trí dải phân cách vẫn không thay đổi (so với đáy cửa sổ). Lần nhấp thứ hai sẽ di chuyển dải phân cách một cách chính xác vì kích thước cửa sổ không thay đổi.

nhập java.awt.BorderLayout;
nhập java.awt.Dimension;
nhập java.awt.GraphicsConfiguration;
nhập java.awt.Insets;
nhập java.awt.Rectangle;
nhập java.awt.Toolkit;
nhập java.awt.event.ActionEvent;

nhập javax.swing.AbstractAction;
nhập javax.swing.JButton;
nhập javax.swing.JFrame;
nhập javax.swing.JLabel;
nhập javax.swing.JSplitPane;

lớp công khai SSCCE {

/**
* @param lập luận không được sử dụng
*/
public static void main(String[] args) {
SSCCE mới();
}

JFrame cuối cùng riêng tư f = JFrame mới("JSplitPane SSCE");
riêng tư cuối cùng JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT,true);

SSCCE công khai() {
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

sp.add(JLabel mới("top"));
sp.add(new JLabel("bottom"));
sp.setResizeWeight(1.0);

f.getContentPane().add(sp);
f.getContentPane().add(new JButton(newAbstractAction("Resize to Default") {
@Ghi đè
public void actionPerformed(ActionEvent e) {
khôi phụcDefaults();
}
}),BorderLayout.PAGE_END);

f.setSize(400,300);
f.setVisible(true);
}

void khôi phụcDefaults() {
f.setSize(f.getWidth(), getDesktopRect(f.getGraphicsConfiguration()).height);
sp.setDividerLocation(sp.getSize().height - 100); // Không hoạt động khi nhấn nút đầu tiên
}

Hình chữ nhật getDesktopRect(GraphicsConfiguration gc) {
Bộ công cụ = Toolkit.getDefaultToolkit();
Kích thước thứ nguyên = toolkit.getScreenSize();
Phần trong phần trong = toolkit.getScreenInsets(gc);
trả về Hình chữ nhật mới (insets.left, insets.top, size.width - (insets.left + insets.right), size.height - (insets.top + insets.bottom));
}

}

Tôi đã nghĩ ra một số cách để giải quyết vấn đề này, nhưng tất cả đều có vẻ hơi rắc rối. Ý tưởng tốt nhất của tôi cho đến nay là gọi giữa việc đặt kích thước khung và đặt vị trí dấu phân cách f.xác thực(), nhưng tôi lo lắng rằng việc buộc xác thực có thể sớm gây ra tác dụng phụ.

Một lựa chọn khác mà tôi nghĩ đến là sử dụng EventQueue.invokeLater() Thực hiện cuộc gọi đặt vị trí dấu phân cách ở cuối hàng đợi sự kiện. Nhưng điều này có vẻ rủi ro đối với tôi - tôi cho rằng JSplitPane sẽ được xác thực vào thời điểm này, điều mà tôi e rằng có thể là một giả định sai.

Có cách nào tốt hơn?

câu trả lời hay nhất

Tôi phải mất một lúc (có lẽ vì ở đây là sáng sớm :-) để hiểu câu hỏi này, vì vậy chỉ để đảm bảo rằng tôi đã hiểu:

  • Kích thước của thành phần phía dưới có thể được người dùng quyết định bất cứ lúc nào
  • Khi khung được thay đổi kích thước, tất cả chiều cao của các thành phần trên cùng sẽ thay đổi
  • Có một tùy chọn để hoàn nguyên về kích thước mặc định, độc lập với mọi cài đặt trước đó
  • "mặc định" có nghĩa là chiều cao của thành phần dưới cùng phải được cố định ở xx

Nếu vậy, giải pháp là tách việc thay đổi kích thước khung khỏi việc thay đổi kích thước thành phần phía dưới. Tùy chọn thứ hai của bạn là chính xác: thay đổi kích thước khung và bọc phần dưới cùng của comp thay đổi kích thước thành InvokeLater (EventQueue hoặc SwingUtilities, không thành vấn đề).

void khôi phụcDefaults() {
f.setSize(f.getWidth(), getDesktopRect(f.getGraphicsConfiguration()).height);
SwingUtilities.invokeLater(new Runnable() {
công khai void run() {
sp.setDividerLocation(sp.getSize().height - 100);

}
});
}

Điều này được đảm bảo hoạt động như mong đợi, vìgọiLater đặt yêu cầu sau tất cả các sự kiện được xếp hàng đợi:

 /**
* Làm cho doRun.run() được thực thi không đồng bộ trên
* Chuỗi gửi sự kiện AWT rốt cuộc sẽ xảy ra.
* các sự kiện AWT đang chờ xử lý đã được xử lý.
* Nếu InvokeLater được gọi từ chuỗi gửi sự kiện --
* ví dụ: từ ActionListener của JButton -- doRun.run() sẽ
* vẫn được hoãn lại cho đến khi tất cả các sự kiện đang chờ xử lý đã được xử lý.

Về swing - cần chiều cao của thành phần Swing không hợp lệ, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/6946880/

30 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress