[英]JComboBox displaying invisible drop-down menu
這是我關於stackoverflow的第一個問題,我需要一些幫助。
作為更強大的Java應用程序的一部分,我想提出一個帶有兩個JComboBoxes的JDialog,該查詢詢問用戶選擇要使用的打印機,然后選擇要使用的關聯分辨率。
但是,如果我選擇一台打印機並且我選擇的分辨率在多台打印機之間共享,那么當我選擇包含相同分辨率的打印機時,為分辨率組合框顯示的下拉菜單將不可見。 下拉菜單的大小是正確的,只是沒有被填充。 試用我的代碼,您將明白我的意思。 例如,我的兩個打印選項是Win32打印機:Kyocera FS-1035MFP KX和Win32打印機:Adobe PDF(打印到pdf)。 它們都共享300x300的分辨率,因此,如果我為Kyocera選擇此分辨率,然后選擇Adobe PDF打印機,則下拉菜單將為正確的尺寸,但將為空。
我不太確定發生了什么。 希望有人可以幫助我。 感謝您的時間。
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Vector;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.PrinterResolution;
import javax.swing.*;
public final class ComboDemo extends JDialog {
private JComboBox selectPrinterBox;
private JLabel selectPrinterLabel;
private JComboBox selectResolutionBox;
private JLabel selectResolutionLabel;
private PrintService printService;
private Resolution resolution;
private DocFlavor flavor;
private PrintRequestAttributeSet aset;
private Vector<Resolution> resolutionVector;
private double xDPI = 300.0;
private double yDPI = 300.0;
public PrintService[] getPrintServices() {
this.flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
this.aset = new HashPrintRequestAttributeSet();
return PrintServiceLookup.lookupPrintServices(flavor, aset);
}
public Vector<Resolution> getVectorOfResolutions(PrintService service) {
PrinterResolution[] supportedResolutions =
(PrinterResolution[]) service.getSupportedAttributeValues(
javax.print.attribute.standard.PrinterResolution.class,
flavor, aset);
Vector<Resolution> resolutions = new Vector<Resolution>();
for (PrinterResolution supportedResolution : supportedResolutions) {
Resolution res = new Resolution();
res.setxDPI(supportedResolution.getResolution(PrinterResolution.DPI)[0]);
res.setyDPI(supportedResolution.getResolution(PrinterResolution.DPI)[1]);
resolutions.add(res);
}
return resolutions;
}
public ComboDemo() {
super();
initComponents();
setContent();
setItemListeners();
}
public void initComponents() {
this.selectPrinterLabel = new JLabel("Select Printer: ");
PrintService[] services = this.getPrintServices();
this.selectPrinterBox = new JComboBox(services);
this.printService = (PrintService) this.selectPrinterBox.getSelectedItem();
this.resolutionVector = this.getVectorOfResolutions(printService);
this.resolution = new Resolution();
this.selectResolutionLabel = new JLabel("Select Resolution: ");
this.selectResolutionBox = new JComboBox(this.resolutionVector);
}
public void setContent() {
JPanel selectPrinterPanel = new JPanel();
selectPrinterPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
selectPrinterPanel.add(selectPrinterLabel);
selectPrinterPanel.add(selectPrinterBox);
JPanel selectResolutionPanel = new JPanel();
selectResolutionPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
selectResolutionPanel.add(selectResolutionLabel);
selectResolutionPanel.add(selectResolutionBox);
JPanel mainPanel = new JPanel();
BoxLayout fP = new BoxLayout(mainPanel, BoxLayout.Y_AXIS);
mainPanel.setLayout(fP);
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
mainPanel.add(selectPrinterPanel);
mainPanel.add(selectResolutionPanel);
this.setContentPane(mainPanel);
this.setTitle("ComboDemo");
this.setLocation(85, 79);
this.pack();
}
public void setItemListeners() {
selectPrinterBox.addItemListener(
new ItemListener() {
@Override
public void itemStateChanged(ItemEvent evt) {
if (evt.getSource().equals(selectPrinterBox)) {
if (evt.getStateChange() == ItemEvent.SELECTED) {
System.out.println("in printerBox itemListener");
printService = (PrintService) selectPrinterBox.getSelectedItem();
resolution = (Resolution) selectResolutionBox.getSelectedItem();
System.out.println("resolution (PrinterBox) : " + resolution.toString());
resolutionVector.clear();
resolutionVector.addAll(getVectorOfResolutions(printService));
if (resolutionVector == null) {
System.out.println("resVec is null");
}
if (resolutionVector.contains(resolution)) {
selectResolutionBox.setSelectedIndex(resolutionVector.lastIndexOf(resolution));
} else {
selectResolutionBox.setSelectedIndex(0);
}
}
}
}
});
selectResolutionBox.addItemListener(
new ItemListener() {
@Override
public void itemStateChanged(ItemEvent evt) {
if (evt.getSource().equals(selectResolutionBox)) {
if (evt.getStateChange() == ItemEvent.SELECTED) {
System.out.println("in resolutionBox itemListener");
resolution = (Resolution) selectResolutionBox.getSelectedItem();
System.out.println("resolution (ResolutionBox) : " + resolution.toString());
xDPI = (double) resolution.getxDPI();
yDPI = (double) resolution.getyDPI();
}
}
}
});
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ComboDemo cd = new ComboDemo();
cd.setVisible(true);
}
});
}
}
class Resolution {
private int xDPI;
private int yDPI;
public int getxDPI() {
return xDPI;
}
public void setxDPI(int xDPI) {
this.xDPI = xDPI;
}
public int getyDPI() {
return yDPI;
}
public void setyDPI(int yDPI) {
this.yDPI = yDPI;
}
@Override
public String toString() {
return (this.getxDPI() + "x" + this.getyDPI());
}
@Override
public boolean equals(Object obj) {
if ( obj instanceof Resolution ) {
Resolution r = (Resolution) obj;
return (this.xDPI == r.xDPI) && (this.yDPI == r.yDPI);
}
return false;
}
@Override
public int hashCode() {
return (this.getxDPI()*1000)+ this.getyDPI();
}
}
問題是,您正在操作要備份正在使用的隱式ComboBoxModel
的Vector
,位於該ComboBoxModel
背后。 如果不包含分辨率,則調用setSelectedIndex(0)
,該方法最終觸發刷新組合框的項目(由於JComboBox
/ DefaultComboBoxModel
的某些內部扭曲)。
所以:
ComboBoxModel
並且要修改JComboBox的內容時,請使用ComboBoxModel
(請看一下DefaultComboBoxModel
) JComboBox
API( removeAllItems
, addItem
) ActionListener
。 而不是ItemListener
只會通知您“選擇更改”事件
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.