- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想为 JAVA 开发一个猜词游戏,但在开发 GUI 时遇到了一些困难。我并不是想开发一个仅使用一个文本字段的简单 GUI,我想开发一个更像移动设备的 GUI。因此,我希望白框显示为单词中字符的占位符。它会像下图这样。
基本上,玩家将能够从下面将字符(我可能会将它们作为按钮或其他东西)拖放到占位符框中,以便与该位置的单词字符进行比较。我尝试过制作文本字段的数组列表,但失败了。有人对如何进行有任何建议吗?
<小时/>根据 MadProgrammer 提供的答案进行更新
使用 MadProgrammer 的一些代码后,我为我的 View 包提出了以下包结构。
> Views
>> GameBoard.java
>> HighScorePanel.java
>> MainPanel.java
>> ScorePanel.java
>> StatisticPanel.java
>> TimerPanel.java
>> ViewConfig.java
>> WordPanel.java
本质上只是一堆放在 GameBoard.java 类中的面板。我遇到的主要问题是 MainPanel.java 类,并保持纵横比。下面是到目前为止的 View 图像,它看起来还算不错,但是单词提示和类别正好与文本字段相对应,并且文本字段不够宽。
如果我放大这个框架,组件之间的间距将保持完全相同,并且不会按比例放大。所以本质上我正在寻找一种动态设置组件之间间距的方法。我已将 GameBoard.java、MainPanel.java 和 StatisticPanel.java 的代码放在下面。 GameBoard由MainPanel和StatisticsPanel组成。统计面板由ScorePanel、TimerPanel和HighScorePanel组成。最后,MainPanel 由 MadProgrammer 之前建议的位组成。
GameBoard.java
package views;
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class GameBoard extends JFrame{
private StatisticsPanel sp = new StatisticsPanel();
private MainPanel mp = new MainPanel();
public GameBoard() {
// set the title for the game board
setTitle(ViewConfig.DEFAULT_GAME_TITLE);
// add panel components to board
add(sp, BorderLayout.PAGE_START);
add(mp, BorderLayout.CENTER);
// set the board size
setSize(ViewConfig.DEFAULT_FRAME_WIDTH, ViewConfig.DEFAULT_FRAME_HEIGHT);
// set the default close operation
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
GameBoard gb = new GameBoard();
// set visible
gb.setVisible(true);
}
}
StatisticsPanel.java
package views;
import java.awt.FlowLayout;
import javax.swing.JPanel;
public class StatisticsPanel extends JPanel {
private ScorePanel sp = new ScorePanel();
private TimerPanel tp = new TimerPanel();
private HighScorePanel hsp = new HighScorePanel();
protected StatisticsPanel() {
// Create a layout for the panel, flow layout in this case as each component should line up
// horizontally
FlowLayout panelLayout = new FlowLayout(FlowLayout.CENTER, (ViewConfig.DEFAULT_FRAME_WIDTH/6), 4);
// Set the panel's layout to the newly created layout
setLayout(panelLayout);
// add components
add(sp);
add(tp);
add(hsp);
}
}
MainPanel.java
package views;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainPanel extends JPanel {
private JButton submitAns, clearAns;
private JLabel wordHint, wordCategory;
private WordPanel wp = new WordPanel(ViewConfig.DEFAULT_GUESS_WORD.length());
protected MainPanel() {
// create the buttons to submit and clear answer
submitAns = new JButton(ViewConfig.DEFAULT_SUBMIT);
clearAns = new JButton(ViewConfig.DEFAULT_CLEAR);
// Create new default labels for the word hint and category
wordHint = new JLabel(ViewConfig.DEFAULT_WORD_HINT);
wordCategory = new JLabel(ViewConfig.DEFAULT_WORD_CATEGORY);
// Set layout manger to GridBagLayout
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(4, 4, 4, 4);
// add all components to panel with following format:
// Word Hint > Input Fields > Word Category > Buttons
add(wordHint, gbc);
add(wp, gbc);
add(wordCategory, gbc);
// Create secondary JPanel to group buttons together, give it flow layout and add button panel to parent
JPanel buttonPanel = new JPanel();
FlowLayout buttonPanelLayout = new FlowLayout(FlowLayout.CENTER, 10, 4);
buttonPanel.add(submitAns, buttonPanelLayout);
buttonPanel.add(clearAns, buttonPanelLayout);
// add button panel to parent
add(buttonPanel);
}
protected JLabel getWordHint() {
return wordHint;
}
protected void setWordHint(String wordHint) {
this.wordHint.setText(wordHint);
}
protected JLabel getWordCategory() {
return wordCategory;
}
protected void setWordCategory(String wordCategory) {
this.wordCategory.setText(wordCategory);
}
}
最佳答案
一个想法可能是使用一系列复合布局,您可以构建它们来满足您的要求。
核心是一个JPanel
,它将呈现特制的JLabel
,能够显示单词的字符,例如......
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GuessingGame());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GuessingGame extends JPanel {
public GuessingGame() {
setLayout(new GridBagLayout());
JLabel label = new JLabel("<html>A few sentences giving either a definition or a<br> few hints about what the word could be</html>");
WordPane wordPane = new WordPane("stackoverflow");
JLabel wordCategory = new JLabel("Word Category");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(4, 4, 4, 4);
add(label, gbc);
add(wordPane, gbc);
JPanel pnlWordCategory = new JPanel(new GridLayout(1, 6, 4, 4));
pnlWordCategory.add(new LetterLabel("A"));
pnlWordCategory.add(new LetterLabel("B"));
pnlWordCategory.add(new LetterLabel("C"));
pnlWordCategory.add(new LetterLabel("D"));
pnlWordCategory.add(new LetterLabel("W"));
pnlWordCategory.add(new LetterLabel("G"));
add(wordCategory, gbc);
add(pnlWordCategory, gbc);
}
}
public class WordPane extends JPanel {
private String word;
private List<JLabel> labels;
public WordPane(String text) {
setLayout(new GridLayout(1, text.length(), 4, 4));
labels = new ArrayList<>(text.length());
for (int index = 0; index < text.length(); index++) {
LetterLabel label = new LetterLabel();
labels.add(label);
add(label);
}
}
}
public class LetterLabel extends JLabel {
public LetterLabel(String text) {
this();
setText(text);
}
public LetterLabel() {
setBorder(new CompoundBorder(new LineBorder(Color.GRAY), new EmptyBorder(4, 4, 4, 4)));
}
@Override
public Dimension getPreferredSize() {
Insets insets = getInsets();
Dimension size = new Dimension();
FontMetrics fm = getFontMetrics(getFont());
size.width = (insets.left + insets.right) + fm.stringWidth("M");
size.height = (insets.top + insets.bottom) + fm.getHeight();
return size;
}
}
}
现在,您可以使用相同的想法,但使用 JTextField
代替 JLabel
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GuessingGame());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GuessingGame extends JPanel {
public GuessingGame() {
setLayout(new GridBagLayout());
JLabel label = new JLabel("<html>A few sentences giving either a definition or a<br> few hints about what the word could be</html>");
WordPane wordPane = new WordPane("stackoverflow");
JLabel wordCategory = new JLabel("Word Category");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(4, 4, 4, 4);
add(label, gbc);
add(wordPane, gbc);
JPanel pnlWordCategory = new JPanel(new GridLayout(1, 6, 4, 4));
pnlWordCategory.add(new LetterLabel("A"));
pnlWordCategory.add(new LetterLabel("B"));
pnlWordCategory.add(new LetterLabel("C"));
pnlWordCategory.add(new LetterLabel("D"));
pnlWordCategory.add(new LetterLabel("W"));
pnlWordCategory.add(new LetterLabel("G"));
add(wordCategory, gbc);
add(pnlWordCategory, gbc);
}
}
public class WordPane extends JPanel {
private String word;
private List<JTextField> fields;
public WordPane(String text) {
setLayout(new GridLayout(1, text.length(), 4, 4));
fields = new ArrayList<>(text.length());
for (int index = 0; index < text.length(); index++) {
JTextField field = new JTextField(2);
fields.add(field);
add(field);
}
}
}
public class LetterLabel extends JLabel {
public LetterLabel(String text) {
this();
setText(text);
}
public LetterLabel() {
setBorder(new CompoundBorder(new LineBorder(Color.GRAY), new EmptyBorder(4, 4, 4, 4)));
}
@Override
public Dimension getPreferredSize() {
Insets insets = getInsets();
Dimension size = new Dimension();
FontMetrics fm = getFontMetrics(getFont());
size.width = (insets.left + insets.right) + fm.stringWidth("M");
size.height = (insets.top + insets.bottom) + fm.getHeight();
return size;
}
}
}
现在,控制。为了管理该流程,您需要某种模型或 Controller ,它能够从 WordPane
获取输入并验证它,然后通知 WordPane
猜测是否有效,因此它可以更新 UI,但这超出了问题的范围
已更新
有多种方法可以实现将角色从一个部分拖动到另一部分,但没有一种方法是简单的。
可能最简单的方法是将控件的 String
值包装在 Transferable
中,并在将其放到其中后更新字段,例如 this for example
关于JAVA - GUI 占位符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28789805/
我的 DateTime 对象使用 DateTime.Now 分配了本地时间。我想知道一旦夏令时开始/结束,这个对象是否会给出正确的当前本地时间。或者我需要解决方法吗? 最佳答案 是的,DateTime
假设我需要“特定类别中可用的项目数量”与“所有项目的数量”的比率。请考虑这样的 MySQL 表: /* mysql> select * from Item; +----+------------+--
我有这张 table http://codepen.io/MetCastle/pen/lxceL我想使用 jQuery 根据 input type="number" 隐藏/显示列。表示整个列: Pro
想要制作一个看起来像这样的网格,其中 div/section 以百分比表示。 margin 在任何地方都是一样的。 http://www.ladda-upp.se/bilder/giefekcmgwm
这将返回 1(又名 TRUE) SELECT DATE_SUB(NOW(), INTERVAL 24*100 HOUR) = DATE_SUB(NOW(), INTERVAL 100 DAY); 10
我一直在尝试在 UIScrollView 中获取 UIView 的转换后的 CGRect。如果我不放大它就可以正常工作,但是一旦我放大,新的 CGRect 就会发生变化。这是让我接近的代码: CGFl
对于家庭作业,我需要在不使用内置模 (%) 运算符的情况下返回 num1 除以 num2 后的余数。我能够通过以下代码让大多数测试通过,但我仍然坚持如何解释给定数字的 -/+ 符号。我需要保留 num
我用 Javascript 创建了一个倒数计时器;它是成功的,期望未完成。事实上,从数学上讲,它是正确的,但是谷歌浏览器的浏览器设置“暂停”(因为没有更好的术语)SetInterval/Timeout
我有两个 的,每个都设置为其容器宽度的 45%。有没有办法使 居中?使得它们在容器的左右两侧有相同的空间,并且它们之间也有空间。 一开始我只是做了每个 50% 并且有 padding: 0px 2
我是一名优秀的程序员,十分优秀!