使用Java,试图用图像显示JButton的可滚动列表,但显示的是文本而不是按钮

使用Java,试图用图像显示JButton的可滚动列表,但显示的是文本而不是按钮,java,swing,Java,Swing,让我更详细地描述我的问题。我搜索了很多,尝试了很多不同的方法,使用validate()和JLabels而不是JButtons,但我的错误肯定在其他地方,因为无论我尝试哪种方法,每次都会出现相同的错误。控制台显示无错误,程序运行正常,但JButtons或JLabels显示为文本。从我所读到的来看,这应该很好用。我肯定错过了什么。。请帮帮我,谢谢!:) 以下是显示为文本的按钮: 下面是代码的重要部分。。。我已经把它切碎了,因为有很多代码 public class MasterViewport imp

让我更详细地描述我的问题。我搜索了很多,尝试了很多不同的方法,使用
validate()
JLabels
而不是
JButtons
,但我的错误肯定在其他地方,因为无论我尝试哪种方法,每次都会出现相同的错误。控制台显示无错误,程序运行正常,但
JButton
s或
JLabel
s显示为文本。从我所读到的来看,这应该很好用。我肯定错过了什么。。请帮帮我,谢谢!:)

以下是显示为文本的按钮:

下面是代码的重要部分。。。我已经把它切碎了,因为有很多代码

public class MasterViewport implements MouseListener, ActionListener, ItemListener, ListSelectionListener {
    JScrollPane tileSelectorScrollPane;
    JFrame tMapEditor;
    ArrayList<Tile> tileArray = new ArrayList<Tile>();
    JButton[] selectorTiles = new JButton[255];
    DefaultListModel<JButton> tileList;
    JList<JButton> tileSelector;
    ...

// lower in the code...
public Container createContentPane() {

    JPanel contentPane = new JPanel(new BorderLayout());
    contentPane.setOpaque(true);

    tileList = new DefaultListModel<JButton>();
    tileSelector = new JList<JButton>(tileList);
    tileSelector.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    tileSelector.setOpaque(true);
    tileSelector.setVisible(true);
    tileSelectorScrollPane = new JScrollPane(tileSelector);
    contentPane.add(tileSelectorScrollPane, BorderLayout.EAST);

    return contentPane;
}

//Now the method where the user selects a file in the select file dialog
//It's where it happens... As i confirm file selection, buttons show up as text.

...
while (!mapCreated) {
    createMap = newMapFile.showDialog(tMapEditor, "Create");
    if (createMap == JFileChooser.APPROVE_OPTION) {
        newMapFileName = newMapFile.getSelectedFile();
            if (!newMapFileName.getName().endsWith(".map")) {
                newMapFileName = new File(newMapFileName.getAbsolutePath() + ".map");
            }
            File[] dirMapFileNames = newMapFile.getCurrentDirectory().listFiles();
            BufferedImage bimg = null;
            String currentFileName = "";
            int width = 0, height = 0;
            String legendStr = "";
            char ch = 0;
            for (int i = 0; i < dirMapFileNames.length; i++) {
                if (newMapFileName.equals(dirMapFileNames[i])) {
                    mapFileAlreadyExists = true;
                }
                if (ch <= 255) {
                    if (dirMapFileNames[i].getName().endsWith(".png")) {
                        try {
                            bimg = ImageIO.read(dirMapFileNames[i]);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        width = bimg.getWidth();
                        height = bimg.getHeight();
                        if (width == 32 && height == 32) {
                            tileImageFound = true;
                            ImageIcon icon = new ImageIcon(dirMapFileNames[i].toString());
                            selectorTiles[ch] = new JButton("test", icon);
                            selectorTiles[ch].setOpaque(true);
                            selectorTiles[ch].setVisible(true);
                            Tile t = new Tile(ch, selectorTiles[ch]);
                            tileArray.add(t);
                            tileList.addElement(selectorTiles[ch]);
                            ch++;
                            legendStr = legendStr + "!" + ch + dirMapFileNames[i].getName();
                        }
                    }
                }
            ...

//Creating and showing the UI..

public static void createAndShowGUI() {
    JFrame tMapEditor = new JFrame("Tile Map Editor");
    MasterViewport masterViewport = new MasterViewport();
    tMapEditor.setJMenuBar(masterViewport.createMenuBar());
    tMapEditor.setContentPane(masterViewport.createContentPane());
    tMapEditor.setLocationRelativeTo(null);
    tMapEditor.setSize(800, 480);
    tMapEditor.setVisible(true);
}
公共类MasterViewport实现MouseListener、ActionListener、ItemListener、ListSelectionListener{
JScrollPane tileSelectorScrollPane;
jt型纤毛机;
ArrayList TilerRay=新的ArrayList();
JButton[]selectorTiles=新JButton[255];
DefaultListModelTileList;
JList tileSelector;
...
//代码中较低的部分。。。
公共容器createContentPane(){
JPanel contentPane=newjpanel(newborderlayout());
contentPane.set不透明(true);
tileList=新的DefaultListModel();
TileSelect=新的JList(tileList);
tileSelector.setSelectionMode(ListSelectionModel.SINGLE_选择);
tileSelector.set不透明(true);
tileSelector.setVisible(真);
tileSelectorScrollPane=新的JScrollPane(tileSelector);
添加(tileSelectorScrollPane,BorderLayout.EAST);
返回内容窗格;
}
//现在是用户在“选择文件”对话框中选择文件的方法
//这就是它发生的地方…当我确认文件选择时,按钮显示为文本。
...
而(!mapCreated){
createMap=newMapFile.showDialog(tmapitor,“创建”);
if(createMap==JFileChooser.APPROVE\u选项){
newMapFileName=newMapFile.getSelectedFile();
如果(!newMapFileName.getName().endsWith(“.map”)){
newMapFileName=新文件(newMapFileName.getAbsolutePath()+“.map”);
}
File[]dirMapFileNames=newMapFile.getCurrentDirectory().listFiles();
BuffereImage bimg=null;
字符串currentFileName=“”;
整数宽度=0,高度=0;
字符串legendStr=“”;
char ch=0;
对于(int i=0;i如果(ch您无法将按钮添加到JList。JList只绘制组件的图像

相反,将
图标添加到
JList
中。JList支持图标的默认呈现程序

如果需要自定义类,还可以创建一个扩展
ImageIcon
TileIcon
来保存额外属性


如果您需要真正的组件,那么不要使用JList。而是使用带有
GridLayout
的JPanel,并将按钮添加到面板中。

您不能将按钮添加到JList。JList只绘制组件的图像

相反,将
图标添加到
JList
中。JList支持图标的默认呈现程序

如果需要自定义类,还可以创建一个扩展
ImageIcon
TileIcon
来保存额外属性


如果您需要真正的组件,那么不要使用JList。而是使用带有
GridLayout
的JPanel,并将按钮添加到面板中。

我通过添加以下内容解决了此问题:

static class MyCellRenderer extends JLabel implements ListCellRenderer<Object> {
    public MyCellRenderer() {
        setOpaque(true);
    }

    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
            boolean cellHasFocus) {
        if (value.getClass().equals(JLabel.class)) {
            JLabel label = JLabel.class.cast(value);
            setIcon(label.getIcon());
            setBorder(label.getBorder());
        }
        return this;
    }
}
静态类MyCellRenderer扩展JLabel实现ListCellRenderer{
公共菌丝体(){
set不透明(true);
}
公共组件GetListCellRenderComponent(JList列表、对象值、int索引、布尔isSelected、,
布尔单元(聚焦){
if(value.getClass()等于(JLabel.class)){
JLabel label=JLabel.class.cast(值);
setIcon(label.getIcon());
setboorder(label.getBorder());
}
归还这个;
}
}

我通过添加以下内容解决了此问题:

static class MyCellRenderer extends JLabel implements ListCellRenderer<Object> {
    public MyCellRenderer() {
        setOpaque(true);
    }

    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
            boolean cellHasFocus) {
        if (value.getClass().equals(JLabel.class)) {
            JLabel label = JLabel.class.cast(value);
            setIcon(label.getIcon());
            setBorder(label.getBorder());
        }
        return this;
    }
}
静态类MyCellRenderer扩展JLabel实现ListCellRenderer{
公共菌丝体(){
set不透明(true);
}
公共组件GetListCellRenderComponent(JList列表、对象值、int索引、布尔isSelected、,
布尔单元(聚焦){
if(value.getClass()等于(JLabel.class)){
JLabel label=JLabel.class.cast(值);
setIcon(label.getIcon());
setboorder(label.getBorder());
}
归还这个;
}
}

当您以前执行“bimg=ImageIO.read(dirMapFileNames[i])”时,为什么要执行“new-ImageIcon(dirMapFileNames[i])”?为什么不直接使用“new-ImageIcon(bimg)”?不向JList添加组件;“tileList.addElement(selectorTiles[ch]);而是使用POJO,Wah包含图像和文本,然后使用ListCellRenderer以您想要的方式显示它们,例如,DefaultListCellRenderer基于JLabelI Dod use new ImageIcon(bimg)之前,但它并没有解决问题,无论如何,我会把它放回^ ^。我也会查看渲染器。是的,谢谢!这只是因为你正在双重加载图像,这似乎很奇怪,这就是为什么你以前做“bimg=ImageIO.read(dirMapFileNames[I])”时要“newimageicon(dirMapFileNames[I].toString()”?为什么不直接使用“new ImageIcon(bimg)”?不要将组件添加到JList;“tileList.addElement(selectorTiles[ch])”;而是使用POJO,Wah包含图像和文本,然后使用ListCellRenderer以您想要的方式显示它们,例如,DefaultListCellRenderer基于JLabelI使用的new ImageIcon(bimg)之前,但它没有解决问题,无论如何,我会把它放回去。我也会检查渲染器是的,谢谢!这只是事实上你