简体   繁体   English

当文本太长时,为什么我的JTextfield文本在左侧而不是右侧?

[英]Why is my JTextfield text going over the left side instead of the right when text is too long for size?

So I'm making a playlist software like itunes or spotify and I'm having trouble with my JTextfields. 因此,我正在制作iTunes或Spotify之类的播放列表软件,而我的JTextfields遇到了麻烦。 When I first read the songs the text that is too long over flows to the right like I want. 当我第一次阅读歌曲时,太长的文本会如我所愿地流向右侧。 But when I reorder the category by clicking on the detail labels at the top, the over flowing text overflows to the left. 但是,当我通过单击顶部的详细信息标签对类别重新排序时,溢出的文本会在左侧溢出。 I can see the text first overflow to the right and then quickly readjust itself to the left. 我可以看到文本首先在右侧溢出,然后迅速将其自身重新调整到左侧。

Here's where I add each jtextfield to my jpanel, the bug might have something to do with my mouse listener but I'm not sure. 在这里,我将每个jtextfield添加到我的jpanel中,该错误可能与我的鼠标侦听器有关,但我不确定。

for (final List<JTextField> inner : songTextFields) {
        if (inner.equals(songTextFields.get(songTextFields.size() - 1))) {
            bottom = true;
        }

        for (int i = 0; i < details.size(); i++) {
            final JTextField textField = inner.get(details.get(i));
            textField.setPreferredSize(detailDimensions.get(i));
            textField.setHorizontalAlignment(JTextField.LEFT);

            if (leftSide) {
                if (bottom) {
                    textField.setBorder(BorderFactory.createCompoundBorder(bottomLeftBorder, emptyBorder));
                } else {
                    textField.setBorder(BorderFactory.createCompoundBorder(leftBorder, emptyBorder));
                }
                leftSide = false;
            } else if (bottom) {
                textField.setBorder(BorderFactory.createCompoundBorder(bottomBorder, emptyBorder));
            } else {
                textField.setBorder(emptyBorder);
            }

            textField.setFont(playlistFont);
            textField.setBackground(textFieldBackground);
            textField.setForeground(Color.WHITE);
            textField.setOpaque(true);
            textField.setEditable(false);

            // textField listeners
            final int usedI = i;
            textField.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 1) {
                        unEditLastTextField(textField);
                        textField.setEditable(true);
                        textField.setSelectionStart(0);
                        textField.setSelectionEnd(textField.getText().length());

                        textField.addKeyListener(new KeyAdapter() {
                            @Override
                            public void keyPressed(KeyEvent e) {
                                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                                    songs.get(songTextFields.indexOf(inner)).setByInt(details.get(usedI), textField.getText());
                                    textField.setText(textField.getText());
                                    textField.setEditable(false);
                                }
                            }
                        });
                    }
                }
            });

            textField.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        // TODO: play song
                    }
                }
            });

            if (i == details.size() - 1) {
                gc.anchor = GridBagConstraints.LINE_START;
                if (bottom) {
                    textField.setBorder(BorderFactory.createCompoundBorder(bottomRightBorder, emptyBorder));
                } else {
                    textField.setBorder(BorderFactory.createCompoundBorder(rightBorder, emptyBorder));
                }

                //textField.setPreferredSize(detailDimensions.get(i));
                //textField.setHorizontalAlignment(JTextField.LEFT);
                panel.add(textField, gc);
            } else {
                //textField.setPreferredSize(detailDimensions.get(i));
                //textField.setHorizontalAlignment(JTextField.LEFT);
                panel.add(textField, gc);
                gc.gridx++;
            }
            System.out.println(textField.getText() + " : " + textField.getPreferredSize() + "  " + textField.getHorizontalAlignment());
        }
        leftSide = true;
        bottom = false;
        textFieldBackground = (textFieldBackground == lightColor ? darkColor : lightColor);
        gc.gridx = 0;
        gc.gridy++;
        gc.anchor = GridBagConstraints.LINE_END;
    } 

Here's where I'm creating each textfield. 这是我创建每个文本字段的地方。 The labels will sort if a detail label is clicked and the songsortby string isn't already equal to that label. 如果单击了详细标签,并且songsortby字符串尚未等于该标签,则标签将进行排序。

private List<List<JTextField>> getSongTextFields(List<Song> songs) {
    switch (songSortBy) {
        case "Title":
            songs = sortSongs(0, songs);
            break;
        case "Artist":
            songs = sortSongs(1, songs);
            break;
        case "Album":
            songs = sortSongs(2, songs);
            break;
        case "Year":
            songs = sortSongs(3, songs);
            break;
        case "Genre":
            songs = sortSongs(4, songs);
            break;
        case "Features":
            songs = sortSongs(5, songs);
            break;
        case "Producers":
            songs = sortSongs(6, songs);
            break;
        default:
            break;
    }

    List<List<JTextField>> textFields = new ArrayList<>();
    for (Song song : songs) {
        List<JTextField> innerLabels = new ArrayList<>();
        innerLabels.add(new JTextField(song.getTitle()));
        innerLabels.add(new JTextField(song.getArtist()));
        innerLabels.add(new JTextField(song.getAlbum()));
        innerLabels.add(new JTextField(song.getYear()));
        innerLabels.add(new JTextField(song.getGenre()));
        innerLabels.add(new JTextField(song.getFeatures()));
        innerLabels.add(new JTextField(song.getProducers()));
        textFields.add(innerLabels);
    }

    return textFields;
}

And finally this is where I'm sorting my songs, I don't think the bug is occurring in this method but you never know. 最后,这是我对歌曲进行排序的地方,我认为这种方法没有发生错误,但您永远不会知道。

private List<Song> sortSongs(int order, List<Song> songs) {
    List<Song> sortedList = new ArrayList<>();

    int j;
    for (int i = 0; i < songs.size(); i++) {
        j = 0;
        while (j < sortedList.size() && songs.get(i).getByInt(order).toUpperCase().compareTo(
                sortedList.get(j).getByInt(order).toUpperCase()) >= 0) {
            j++;
        }
        sortedList.add(j, songs.get(i));
    }

    return sortedList;
}

If you guys want to see any other parts of my code just to let me know, thanks for the help. 如果你们只是想让我知道代码的其他部分,谢谢您的帮助。

I think your problem is caused by the fact that you are messing with sizing and alignment of your JTextFields at runtime (after they have been layouted), without any sanity checks and - even more important - without validating and redrawing the parent layouts. 我认为您的问题是由以下事实引起的:您在运行时(对JTextFields进行了布局)对JTextField的大小和对齐感到困惑,没有进行任何健全性检查,更重要的是,没有验证和重绘父布局。

This is the code i refer to: 这是我指的代码:

final JTextField textField = inner.get(details.get(i));
textField.setPreferredSize(detailDimensions.get(i));
textField.setHorizontalAlignment(JTextField.LEFT);

The best solution is to avoid the problem altogether by desiging your components in a way that they don't need to change their shape so much. 最好的解决方案是通过以不需要太多改变形状的方式设计组件来完全避免该问题。 Use a table as someone else suggested; 像其他人建议的那样使用桌子; maybe a textarea with richtext/html can solve your problem; 也许一个带有richtext / html的textarea可以解决您的问题; maybe swapping only the values in between JTextFields is all you really need? 也许只需要在JTextFields之间交换就可以了?

If you must take the approach with resizing and all that: 如果您必须采用调整大小的方法以及所有这些方法:

  1. Make sure that containing (parent) components offer enough space and will furthermore adapt properly. 确保包含(父)组件提供足够的空间,并且将进一步正确地适应。
  2. Invoke revalidate()/validate() and repaint() of your parent 调用您父母的revalidate()/ validate()repaint()
    container(s) after messing with size and alignment of your 弄乱您的尺寸和对齐方式后的容器
    JTextFields. JTextFields。 See Dynamically Add Components to a JDialog 请参见将组件动态添加到JDialog

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM