Java Swing: рабочий Swing, invokeAndWait и перекрывающиеся JLabels
Эй, ребята, я пришел с 2 проблемами, обе из которых связаны с Java Swing. Я занимаюсь разработкой карточной игры на Java. Я использую списки типов для хранения значений каждой карты, и у меня есть основной метод Play(), который вызывает обновления GUI с использованием invokeLater и подхода Singleton к моему классу GUI.
Первый вопрос довольно прост. Я создаю карты в 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(), но ничего не получил. Любая помощь, которую вы можете оказать здесь, будет очень кстати.
Мой второй вопрос касается использования 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 вручную.