I'm currently creating a domino game in java. The idea is to load the domino images, rotate them if necessary, and then display them on the screen.
A few weeks ago I posted a question asking how to rotate an imageIcon in Java.
Someone replied as follows: "The Unicode charset includes dominoes".
So if I understand this correctly, instead of loading domino images I can use Unicode character set to display the dominoes on the screen? I cannot find any examples on Internet how to do this. Any one can give me an example of how this is done?
Dominoes are represented by UTF8 characters from U+1F030 to U+1F09F. There is a special block for them.
🀰 🀱 🀲 🀳 🀴 🀵 🀶 🀷 🀸 🀹 🀺 🀻 🀼 🀽 🀾 🀿
🁀 🁁 🁂 🁃 🁄 🁅 🁆 🁇 🁈 🁉 🁊 🁋 🁌 🁍 🁎 🁏
🁐 🁑 🁒 🁓 🁔 🁕 🁖 🁗 🁘 🁙 🁚 🁛 🁜 🁝 🁞 🁟
🁠 🁡 🁢 🁣 🁤 🁥 🁦 🁧 🁨 🁩 🁪 🁫 🁬 🁭 🁮 🁯
🁰 🁱 🁲 🁳 🁴 🁵 🁶 🁷 🁸 🁹 🁺 🁻 🁼 🁽 🁾 🁿
🂀 🂁 🂂 🂃 🂄 🂅 🂆 🂇 🂈 🂉 🂊 🂋 🂌 🂍 🂎 🂏
🂐 🂑 🂒 🂓
According to https://unicode-table.com:
Domino Tiles is a Unicode block containing characters for representing game situations in dominoes. The block includes symbols for the standard six dot tile set and backs in horizontal and vertical orientations
See https://unicode-table.com/en/blocks/domino-tiles/
According to The Unicode Standard, Version 10.0:
The domino tile symbols do not represent the domino pieces per se, but instead constitute graphical symbols for particular orientations of the dominoes, because orientation of the tiles is significant in discussion of dominoes play. Each visually distinct rotation of a domino tile is separately encoded. Thus, for example, both U+1F081 domino tile vertical-04-02 and U+1F04F
domino tile horizontal-04-02 are encoded, as well as U+1F075 domino tile vertical-02-04 and U+1F043 domino tile horizontal-02-04. All four of those symbols represent the same game tile, but each orientation of the tile is visually distinct and requires its own symbol for text. The digits in the character names for the domino tile symbols reflect the dot patterns on the tiles.
You also have to choose a font able to display them.
The previous answer is correct. However:
More convenient page for characters: http://www.alanwood.net/unicode/domino-tiles.html
Plus, the actual printing of those characters is described here.
An example of printing one of the dominoes:
class Scratch {
public static void main(String[] args) {
System.out.println(new String(Character.toChars(127026)));
}
}
This prints 🀲 on IntelliJ's console. Your results may vary, depending on your font.
The following code shows how to ascertain the installed fonts that support displaying this group of Unicode characters (3 out of over 250 fonts installed here), and displaying them in a text area.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.EmptyBorder;
import java.util.Vector;
public class DominoTiles {
private JComponent ui = null;
public static final int DOMINO_TILE_START = 127024;
public static final int DOMINO_TILE_END = 127123;
String dominoeTiles;
JTextArea textArea = new JTextArea(4, 10);
DominoTiles() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
StringBuilder sb = new StringBuilder();
for (int ii = DOMINO_TILE_START; ii <= DOMINO_TILE_END; ii++) {
String s = new String(Character.toChars(ii));
sb.append(s);
}
textArea.setText(sb.toString());
textArea.setLineWrap(true);
ui.add(new JScrollPane(textArea));
String[] fontFamilies = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
final Vector<String> compatibleFonts = new Vector<>();
for (String fontFamily : fontFamilies) {
Font f = new Font(fontFamily, Font.PLAIN, 1);
if (f.canDisplayUpTo(sb.toString()) < 0) {
compatibleFonts.add(fontFamily);
}
}
final JList list = new JList(compatibleFonts);
ui.add(new JScrollPane(list), BorderLayout.LINE_START);
ListSelectionListener listSelectionListener = new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
String fontFamily = list.getSelectedValue().toString();
Font f = new Font(fontFamily, Font.PLAIN, 60);
textArea.setFont(f);
}
}
};
list.addListSelectionListener(listSelectionListener);
list.setSelectedIndex(0);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
DominoTiles o = new DominoTiles();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
This example shows how to turn Unicode characters into images (plus a few more tricks of rendering them).
Related
Yes, I read through the various post with regards to this but their scenarios where a bit different and didn't explain what is going on in the background.
Lets say the following program is created in a country where decimal points use '.' notation but then executed in a country which uses ',' notation.
For example, 1.23 and 1,23 are technically the same number but with different notations.
import java.awt.FlowLayout;
import java.awt.event.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import javax.swing.*;
class LocaleTestDecimal extends JFrame implements ActionListener
{
static JTextField t;
static JFrame f;
static JButton b;
static JLabel l;
static JLabel localLabel;
LocaleTestDecimal()
{
}
public static void main(String[] args)
{
Locale locale = Locale.getDefault();
f = new JFrame("Locale = " + locale.toString());
l = new JLabel("nothing entered");
b = new JButton("submit");
LocaleTestDecimal te = new LocaleTestDecimal();
b.addActionListener(te);
t = new JTextField(16);
//default value of 1.23
t.setText(Double.toString(1.23));
NumberFormat format = NumberFormat.getInstance(Locale.ITALY);
Number number = null;
try {
number = format.parse("1.23");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
double d = number.doubleValue();
l.setText(Double.toString(number.doubleValue()));
JPanel p = new JPanel();
p.add(t);
p.add(b);
p.add(l);
f.add(p);
f.setSize(300, 300);
f.show();
}
// if the button is pressed
public void actionPerformed(ActionEvent e)
{
String s = e.getActionCommand();
if (s.equals("submit")) {
// set the text of the label to the text of the field
l.setText(t.getText());
// set the text of field to blank
t.setText(" ");
}
}
}
The above code runs fine and as expected when my Locale is set to English.
After changing my Windows Region and Format to Italy.
And changed my Eclipse VM arguments
The numbers still use the '.' notation for numbers. Even using the NumberFormat didn't seem to change the value on the JFrame.
The title of the JFrame contains the locale which confirms it is Italy.
Question 1:
Why am I not seeing numbers using the ',' notation?
Question 2:
As these numbers expected to dynamically change simply based on the Locale set?
I have a simple program just need to set the character whose Unicode value larger the character data type (supplementary character) on JTextField when the button is click .Tell me i am really fed up and how i will do it .This problem have already taken my 4 days.
//importing the packages
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
//My own custom class
public class UnicodeTest implements ActionListener
{
JFrame jf;
JLabel jl;
JTextField jtf;
JButton jb;
UnicodeTest()
{
jf=new JFrame();// making a frame
jf.setLayout(null); //seting the layout null of this frame container
jl=new JLabel("enter text"); //making the label
jtf=new JTextField();// making a textfied onto which a character will be shown
jb=new JButton("enter");
//setting the bounds
jl.setBounds(50,50,100,50);
jtf.setBounds(50,120,400,100);
jb.setBounds(50, 230, 100, 100);
jf.add(jl);jf.add(jtf);jf.add(jb);
jf.setSize(400,400);
jf.setVisible(true); //making frame visible
jb.addActionListener(this); // registering the listener object
}
public void actionPerformed(ActionEvent e) // event generated on the button click
{ try{
int x=66560; //to print the character of this code point
jtf.setText(""+(char)x);// i have to set the textfiled with a code point character which is supplementary in this case
}
catch(Exception ee)// caughting the exception if arrived
{ ee.printStackTrace(); // it will trace the stack frame where exception arrive
}
}
// making the main method the starting point of our program
public static void main(String[] args)
{
//creating and showing this application's GUI.
new UnicodeTest();
}
}
Since you are not giving enough information on what's wrong, I can only guess that either or both:
You are not using a font that can display the character.
You are not giving the text field the correct string representation of the text.
Setting a font that can display the character
Not all fonts can display all characters. You have to find one (or more) that can and set the Swing component to use that font. The fonts available to you are system dependent, so what works for you might not work for others. You can bundle fonts when you deploy your application to ensure it works for everyone.
To find a font on your system that can display your character, I used
Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (Font f : fonts) {
if (f.canDisplay(66560)) {
System.out.println(f);
textField.setFont(f.deriveFont(20f));
}
}
The output (for me) is a single font, so I allowed myself to set it in the loop:
java.awt.Font[family=Segoe UI Symbol,name=Segoe UI Symbol,style=plain,size=1]
as also noted in the comments to the question by Andrew Thompson.
Giving the text field the correct string representation
The text fields require UTF-16. Supplementary characters in UTF-16 are encoded in two code units (2 of these: \u12CD). Assuming you start from a codepoint, you can convert it to characters and then make a string from them:
int x = 66560;
char[] chars = Character.toChars(x); // chars [0] is \uD801 and chars[1] is \uDC00
textField.setText(new String(chars)); // The string is "\uD801\uDC00"
// or just
textField.setText(new String(Character.toChars(x)));
as notes by Andrew Thompson in the comments to this answer (previously I used a StringBuilder).
I want to display a grid of 400 identically-sized JPanels. The usual approach seems to be to create and lay out all the panels, and then actually display them. In my application, however, most of the panels actually start out hidden (think "minesweeper", but with much more complicated panels), so I'd love to be able to display an "empty" grid, and then add the panels to it as I need them. Two approaches I've considered:
Dispense with a layout manager and simply add panels at the appropriate absolute coordinates as necessary.
Use a layout manager, but start off filling up the table with dummy components and replace them with the complicated ones as I go.
Using either of these approaches, however, I seem to need to know the panel size in advance, which I don't. I could fix this by building a sample panel and measuring it, but that seems rather ugly, and duplicates a bunch of code. Is there some other way to do this?
Use the flyweight pattern to render only visible panels. The approach is illustrated in JTable renderers and outlined here.
I would not use panels or custom painting here. Instead:
Component: JToggleButton
Layout: GridLayout
Tiles: Icon (standard, focused, pressed, selected etc.)
E.G.
import java.awt.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
class MineSweeper {
public static final int COLS = 20;
public static final int ROWS = 20;
public static void main(String[] args) throws Exception {
URL urlDefault = new URL("http://i.stack.imgur.com/in9g1.png");
URL urlPressed = new URL("http://i.stack.imgur.com/1lgtq.png");
URL urlSelected = new URL("http://i.stack.imgur.com/wCF8S.png");
final Image imgDefault = ImageIO.read(urlDefault);
final Image imgPressed = ImageIO.read(urlPressed);
final Image imgSelected = ImageIO.read(urlSelected);
Runnable r = new Runnable() {
#Override
public void run() {
JPanel gui = new JPanel(new GridLayout(ROWS, COLS, 2, 2));
ImageIcon iiDefault = new ImageIcon(imgDefault);
for (int ii = 0; ii < COLS; ii++) {
for (int jj = 0; jj < ROWS; jj++) {
JToggleButton tb = new JToggleButton(iiDefault);
tb.setContentAreaFilled(false);
tb.setMargin(new Insets(0,0,0,0));
tb.setPressedIcon(new ImageIcon(imgPressed));
tb.setSelectedIcon(new ImageIcon(imgSelected));
gui.add(tb);
}
}
JOptionPane.showMessageDialog(null, gui);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
When I try to use the Wingdings font (or other symbol fonts), the text comes out as rectangles instead of the correct text. How do I get the correct characters to show?
import java.awt.*;
import javax.swing.*;
public class WingdingsFontDisplay extends JFrame
{
public static void main(String[] args)
{
new WingdingsFontDisplay();
}
public WingdingsFontDisplay()
{
this.setSize(500,150);
this.setTitle("Fun with Fonts");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//This shows that I do have "Wingdings" available
GraphicsEnvironment g;
g = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fonts = g.getAvailableFontFamilyNames();
for(String f : fonts)
{
System.out.println(f);
}
//Displaying text in the Wingdings font shows rectangles
JLabel wingdingsText = new JLabel("All work and no play makes Jack a dull boy");
Font f1 = new Font("Wingdings", Font.PLAIN, 14);
wingdingsText.setFont(f1);
this.add(wingdingsText, BorderLayout.NORTH);
//Displaying text in Arial works correctly
JLabel arialText = new JLabel("All work and no play makes Jack a dull boy");
Font f2 = new Font("Arial", Font.PLAIN, 14);
arialText.setFont(f2);
this.add(arialText, BorderLayout.SOUTH);
this.setVisible(true);
}
}
You need to use the appropriate Unicode range for the symbols you seek. In Java, symbols are not overlaid on the ASCII range, but have their own distinct character codes.
You can find a reference to the appropriate symbol codes at http://unicode.org/~asmus/web-wing-ding-ext.pdf . Most common symbols are in the 0x2200 and 0x2700 Unicode ranges.
Your Java install may include the SymbolTest sample applet, which makes it straightforward to preview the presentation of Unicode ranges with available fonts. Be warned, however, that better Java implementations will use font substitutions for symbols or characters not in the specified font, so you'll want to be sure you're actually getting the specified font.
I'm currently working on a rather complex application. My job is to build parts of the GUI.
The main area is derived for JTable and contains all application relevant data. There are a few elements on top of the Table, that allow the user to control the way the data is shown in the table.
The options relevant to the task at hand are:
Changing of number of columns,
Independently changing of width of columns (not by means of JTableHeader) and
Entering one filter term per column to select specific rows of the data.
The main goal in this szenario is to create a Component (probably JTextField) for every column in the current viewsetting, which is accuratly aligned with that column (although it changes size at runtime).
First question:
The alignment doesn't work. I can't get the width of the TextFields to match the width of the columns.
How do i get it to work?
Second problem:
I want the individual filters to be chained. That is, if the user decides to enter more then one filter string, all of them should be evaluated for their respective columns and only the rows that match all filters should be shown. So far the input in a second TextField delets the first filter (which is working decently using RowFilter.regexFilter).
How do i get this to work?
Please let me know, which code snippets could be useful to you and i will be glad to post them.
Thanks in advance for any help given.
Regards, DK
I can't get the width of the
TextFields to match the width of the
columns
This example should get you started:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableFilterRow extends JFrame implements TableColumnModelListener
{
private JTable table;
private JPanel filterRow;
public TableFilterRow()
{
table = new JTable(3, 5);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
table.getColumnModel().addColumnModelListener( this );
// Panel for text fields
filterRow = new JPanel( new FlowLayout(FlowLayout.CENTER, 0 , 0) );
for (int i = 0; i < table.getColumnCount(); i ++)
filterRow.add( new JTextField("" + i) );
columnMarginChanged( new ChangeEvent(table.getColumnModel()) );
getContentPane().add(filterRow, BorderLayout.NORTH);
}
// Implement TableColumnModelListener methods
// (Note: instead of implementing a listener you should be able to
// override the columnMarginChanged and columMoved methods of JTable)
public void columnMarginChanged(ChangeEvent e)
{
TableColumnModel tcm = table.getColumnModel();
int columns = tcm.getColumnCount();
for (int i = 0; i < columns; i ++)
{
JTextField textField = (JTextField)filterRow.getComponent( i );
Dimension d = textField.getPreferredSize();
d.width = tcm.getColumn(i).getWidth();
textField.setPreferredSize( d );
}
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
filterRow.revalidate();
}
});
}
public void columnMoved(TableColumnModelEvent e)
{
Component moved = filterRow.getComponent(e.getFromIndex());
filterRow.remove(e.getFromIndex());
filterRow.add(moved, e.getToIndex());
filterRow.validate();
}
public void columnAdded(TableColumnModelEvent e) {}
public void columnRemoved(TableColumnModelEvent e) {}
public void columnSelectionChanged(ListSelectionEvent e) {}
public static void main(String[] args)
{
JFrame frame = new TableFilterRow();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
only the rows that match all filters
should be shown
Read the JTable API and follow the link to the Swing tutorial on "How to Use Tables" where you will find the TableFilterDemo. You can easily modify the code to use "and" filters. The code would be something like:
// rf = RowFilter.regexFilter(filterText.getText(), 0);
List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);
filters.add(RowFilter.regexFilter(filterText.getText(), 0));
filters.add(RowFilter.regexFilter(filterText.getText(), 1));
rf = RowFilter.andFilter(filters);
This examples shares a single text field looking for the same string in multiple columns. You would obviously use your individual text fields.