这是我关于stackoverflow的第一个问题,我需要一些帮助。
作为更宏大的java应用程序的一部分,我想提出一个带有几个JComboBox的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();
}
}
答案 0 :(得分:1)
问题在于,您正在操纵Vector
备份您正在使用的隐式ComboBoxModel
,位于ComboBoxModel
的后面。如果未包含分辨率,则调用setSelectedIndex(0)
,最终会触发刷新组合框的项目(因为JComboBox
/ DefaultComboBoxModel
的内部扭曲。
所以:
ComboBoxModel
,要修改JComboBox的内容,请使用ComboBoxModel
(请查看DefaultComboBoxModel
)JComboBox
API(removeAllItems
,addItem
)ActionListener
。而不是ItemListener
您只会收到“选择更改”事件的通知