Java Swing: рабочий Swing, invokeAndWait и перекрывающиеся JLabels

Эй, ребята, я пришел с 2 проблемами, обе из которых связаны с Java Swing. Я занимаюсь разработкой карточной игры на Java. Я использую списки типов для хранения значений каждой карты, и у меня есть основной метод Play(), который вызывает обновления GUI с использованием invokeLater и подхода Singleton к моему классу GUI.

  1. Первый вопрос довольно прост. Я создаю карты в GUI, используя JLabels вот так; присоединение соответствующих слушателей и добавление их в соответствующую панель, в данном случае "Панель человеческой руки":

     for (int i = 0; i < (HumanHand.size()); i++)
                {
                    Card card = HumanHand.get(i);
    
                    BufferedImage cardImage = null;
    
                    try {
    
                        cardImage = ImageIO.read(new File("card/" + card + ".jpg"));
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                    JLabel picLabel = new JLabel(new ImageIcon( cardImage ));
    
                    picLabel.addMouseListener((MouseListener) me);
                    HumanHandDisplay.add(picLabel);
    
                } 
                //HumanHandDisplay.validate();
                HumanHandDisplay.updateUI();
    

Проблема, с которой я сталкиваюсь, состоит в том, что, когда у человеческой руки больше 7 карт или около того, она создает большую площадь панели и начинает новый ряд карт ниже. Что я хотел бы сделать, так это то, что когда рука достигает определенного размера, карты начинают перекрывать друг друга (как если бы вы держали карты в руке). Я возился с.validate(), но ничего не получил. Любая помощь, которую вы можете оказать здесь, будет очень кстати.

  1. Мой второй вопрос касается использования Swing Worker для возврата выбора карты игрока-человека. Я немного читал о работниках Swing, но я не уверен, как лучше всего реализовать их в моей собственной игре. В настоящее время, используя консоль, у меня есть сканер, который принимает ввод int в качестве выбора (место конкретной карты в ArrayList). Я хотел бы, чтобы этот int был выбран, нажав на карту в руке игроков. На данный момент я использую:

                 String name = "" + i;
                picLabel.setName(name);
    

    чтобы установить имена Card JLabels в int в цикле for, создавая их (как показано ^^), и я использую:

     public void mouseClicked(MouseEvent e) {
        String name = ((JLabel)e.getSource()).getName();
        System.out.println("Working " + name);
        selection = Integer.parseInt(name);         
    }
    

    Чтобы вернуть этот int, когда нажата одна из карточек. Вот что я использовал для вызова методов GUI из Play(), а также:

            SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                GUI.getInstance().UpdateHand();
    
            }
        }); 
    

    У меня вопрос, как я могу заставить метод Play вызвать метод в классе GUI, который настраивает раздачу с соответствующими слушателями (на данный момент давайте назовем это GUIPlayerSelection()), а затем дождаться, когда игрок нажмет карту, которая затем возвращает int в метод Play() моего основного класса, который представляет выбранную карту. Я не уверен, как использовать invoke и wait, например, если я использую invoke и wait, он просто будет ждать установки карточек или будет ждать, пока метод mouseClicked() завершит работу? Или мне придется сделать что-то еще, чтобы убедиться, что он ждет нажатия мыши после настройки руки? И как тогда я верну этот int? Мне сказали использовать работника качания, но если бы кто-то мог объяснить, как я могу реализовать это в этом случае, это было бы здорово.

Заранее спасибо.

1 ответ

По первому вопросу у вас возникла проблема с перерисовкой рамки или с расположением карт?

Если последнее, то, возможно, вы захотите взглянуть на Java Layout Manager, он описывает, как панель контента внутри вашего JFrame организует добавленные к нему компоненты.

Если ни один из них не будет работать для вас (и я не думаю, что они будут соответствовать тому, что вы описали), вы можете использовать метод setBounds, чтобы выровнять JLabels вручную.

Другие вопросы по тегам