自从我构建桌面JAVA应用程序以来已经有一段时间了......在经过大量文档和实施测试之后,我仍然没有找到图像网格解决方案。
Java是否缺少这样一个现成的组件(?!),或者你告诉我刷新我的google-fu。:)
我有一个非常简单的技术前提:一个允许用户选择图像的JDialog。输入是一个包含文件名的Map<Integer, String>
列表。输出是用户选择的Integer
密钥。 GUI也很简单:用户使用鼠标或键盘选择1个图像,并关闭对话框。所有图像都是80x80像素,并从文件名加载而不是资源。
我今天早上尝试了几种方法:
myJList.setModel()
,但我无法接受我的地图&lt;&gt;并显示缩略图。 (overcomplicates!)myJPanel.setlayout(new FlowLayout(..))
实现myJPanel.add(new JButton(..))
,这只是在JPanel上创建了一堆JButton,每个都需要一个事件处理程序。我想知道滚动和键盘输入是如何工作的,以及我应该如何保持/引用我的Map<>
键值。 (overcomplicates?)代替你的回答,我现在正在研究后者,这应该有效,但我不能相信每个人都需要在这里重新发明相同的GUI轮。如何让用户从我的Map<Integer, String>
中选择图片?是否有JAVA库/小部件/组件,我应该避免这种情况?
我希望这不会被修改,我没有错误的工作实现向你们展示..这个问题是关于如何/在哪里找到组件或哪种方法会更好。它的2014年和我不能相信JAVA仍然需要我建立我自己的“GUI组件”只是为了看到一些图像......甚至Delphi或Mono都没有这样做。
答案 0 :(得分:4)
如果你想要的只是一个图像网格,并且可以选择它们,可以考虑使用JList,用适当的ImageIcons填充它,并给它一个ListSelectionListener。在监听器中,您可以在进行选择时关闭封闭对话框。
你说:
尝试并实现myJList.setModel(),但我不能把它拿到我的Map&lt;&gt;并显示缩略图。 (overcomplicates!)
您需要使用Map填充ListModel,并将该Model设置为JList的模型。
例如:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
@SuppressWarnings("serial")
public class ImageGridPanel extends JPanel {
public static final String PATH = "http://images-2.drive.com.au/2011/";
public static final String[] CARS = {
"04/15/2308961/giulietta_1024-80x80.jpg",
"11/18/2781958/audi-a1-sportback_600-80x80.jpg",
"12/23/2856762/fiat-500-80x80.jpg",
"01/12/2129944/Honda-Civic-Sedan-concept-1_600-80x80.jpg",
"12/23/2856581/mini-roadster-80x80.jpg",
"12/23/2856571/hyundai-veloster-80x80.jpg",
"12/23/2856771/hyundai-i30-80x80.jpg",
"12/23/2856580/mini-coupe-80x80.jpg" };
private DefaultListModel<Car> carModel = new DefaultListModel<>();
final JTextField textField = new JTextField(20);
public ImageGridPanel() {
for (String carPath : CARS) {
String path = PATH + carPath;
try {
URL imgUrl = new URL(path);
BufferedImage img = ImageIO.read(imgUrl);
ImageIcon icon = new ImageIcon(img);
String name = carPath.substring(carPath.lastIndexOf("/"));
name = name.substring(1, name.lastIndexOf("-"));
carModel.addElement(new Car(name, icon));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
ShowGridAction showAction = new ShowGridAction("Car Grid", carModel);
JButton showGridBtn = new JButton(showAction);
add(showGridBtn);
add(textField);
}
private class ShowGridAction extends AbstractAction {
private CarGridPanel carGridPanel;
public ShowGridAction(String name, DefaultListModel<Car> carModel) {
super(name);
carGridPanel = new CarGridPanel(carModel);
}
public CarGridPanel getCarGridPanel() {
return carGridPanel;
}
@Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor((Component) e.getSource());
JDialog dialog = new JDialog(win, "Cars", ModalityType.APPLICATION_MODAL);
dialog.add(carGridPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
int x = dialog.getLocation().x;
int y = dialog.getLocation().y - 150;
dialog.setLocation(x, y);
dialog.setVisible(true);
Car selectedCar = carGridPanel.getSelectedCar();
if (selectedCar != null) {
textField.setText(selectedCar.getName());
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ImageGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ImageGridPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Car {
String name;
Icon icon;
public Car(String name, Icon icon) {
this.name = name;
this.icon = icon;
}
public String getName() {
return name;
}
public Icon getIcon() {
return icon;
}
}
@SuppressWarnings("serial")
class CarGridPanel extends JPanel {
private JList<Car> carList = new JList<>();
private Car selectedCar;
public CarGridPanel(ListModel<Car> model) {
carList.setModel(model);
carList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
carList.setVisibleRowCount(2);
carList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
Car carValue = (Car) value;
value = carValue.getIcon();
} else {
value = "";
}
return super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
}
});
setLayout(new BorderLayout());
add(new JScrollPane(carList));
carList.addListSelectionListener(new ListListener());
}
public Car getSelectedCar() {
return selectedCar;
}
private class ListListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
selectedCar = carList.getSelectedValue();
Window win = SwingUtilities.getWindowAncestor(CarGridPanel.this);
win.dispose();
}
}
}
答案 1 :(得分:1)
不,Java没有你想要的东西。
Java是一种通用编程语言,而不是工具集,尤其不是专用的桌面GUI工具集。这不是对语言的诋毁,只是对未达到目的的陈述。
如果Delphi或Mono或其他任何东西都有你的特定小部件,那么我建议你编程。这不是对你的诋毁,只是观察一下,如果你不想将你想要的小部件放在较低级别的组件和代码中,那么Java就不是你用来做它的正确语言/工具。
至于不相信Java“仍然需要”你构建自己的组件,我只能说你不能选择哪种语言提供哪些功能。我很高兴Java不会被你的组件所困扰,而且人们喜欢你的数百个人会想到Java应该提供的。它足够大。