I have some Javascript code that acts on an pixel array defined like so:
screen = {'width':160, 'height':144, 'data':new Array(160*144*4)};
...
canvas.putImageData(GPU._scrn, 0,0);
Where screen is 1D array of width * height * 4 values representing the colors as detailed here: https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas
Is there a convenience method to paint this array to the screen as is? If not, what's the easiest way to paint this array using Swing?
BufferedImage is probably the most flexible choice. You can use it as an Icon or override paintComponent() for the full generality of Java2D.
package overflow;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/** #see http://stackoverflow.com/questions/7298492 */
public class PiRaster extends JPanel {
private static final int W = 30;
private static final int H = 30;
private static List<Integer> pi = new ArrayList<Integer>();
private final List<Integer> clut = new ArrayList<Integer>();
private BufferedImage image;
public PiRaster() {
this.setPreferredSize(new Dimension(W * 16, H * 10));
String s = ""
+ "31415926535897932384626433832795028841971693993751"
+ "05820974944592307816406286208998628034825342117067"
+ "98214808651328230664709384460955058223172535940812"
+ "84811174502841027019385211055596446229489549303819"
+ "64428810975665933446128475648233786783165271201909"
+ "14564856692346034861045432664821339360726024914127";
for (int i = 0; i < s.length(); i++) {
pi.add(s.charAt(i) - '0');
}
for (int i = 0; i < 10; i++) {
clut.add(Color.getHSBColor(0.6f, i / 10f, 1).getRGB());
}
image = new BufferedImage(W, H, BufferedImage.TYPE_INT_ARGB);
int i = 0;
for (int row = 0; row < H; row++) {
for (int col = 0; col < W; col++) {
image.setRGB(col, row, clut.get(pi.get(i)));
if (++i == pi.size()) {
i = 0;
}
}
}
}
private static class ClutPanel extends JPanel {
private int i;
public ClutPanel(List<Integer> rgbList) {
this.setLayout(new GridLayout(1, 0));
for (Integer rgb : rgbList) {
JLabel label = new JLabel(String.valueOf(i++), JLabel.CENTER);
label.setOpaque(true);
label.setBackground(new Color(rgb));
this.add(label);
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PiRaster pr = new PiRaster();
Icon icon = new ImageIcon(pr.image);
frame.add(new JLabel(icon), BorderLayout.WEST);
frame.add(pr, BorderLayout.CENTER);
frame.add(new ClutPanel(pr.clut), BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
});
}
}
Related
I want to plot many sinusoids with different frequencies on a panel, but because painting is destructive, I cannot achieve this. I can only see the last sinusoid plotted.
In the code, the generateSinus() method is called only three times, but it might be called many times and I don't want to call g.fillOval() method for each sinusoid in the paintComponent() method.
Is there a way to achieve non-destructive painting and see all sinusioids with different frequencies?
Please see the code below:
package testdrawsinus;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestDrawSinus extends JPanel
{
private static double[] x;
private static double[] y;
private static boolean buttonClicked = false;
private static JPanel panel = new TestDrawSinus();
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GREEN);
if (buttonClicked)
{
for (int i=0; i<x.length; i++)
{
g.fillOval((int)x[i] + panel.getWidth()/2, -1*((int)y[i]) + panel.getHeight()/2, 10, 10);
}
buttonClicked = false;
}
}
private static void generateSinus(int freq)
{
x = new double[200];
y = new double[200];
for (int i=0; i<=199; i++)
{
x[i]= (double)i;
y[i] = 100*Math.sin(2*Math.PI*freq*i/200);
}
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
panel.setLayout(null);
panel.setBounds(20,20, 700,400);
panel.setBackground(Color.BLACK);
frame.add(panel);
JButton button1 = new JButton();
button1.setText("plot");
button1.setBounds(300, 500, 150, 50);
frame.add(button1);
button1.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
buttonClicked = true;
generateSinus(1);
panel.repaint();
generateSinus(2);
panel.repaint();
generateSinus(3);
panel.repaint();
}
});
}
}
Thanks for your help.
There are a number of ways you might do this, one way would be to seperate each series into its own model, then have the panel paint each model, for example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
private Color[] masterColors = new Color[]{
Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY,
Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.PINK,
Color.RED, Color.WHITE, Color.YELLOW
};
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
TestDrawSinus sinusPane = new TestDrawSinus();
JFrame frame = new JFrame();
frame.add(sinusPane);
JButton button1 = new JButton();
button1.setText("plot");
frame.add(button1, BorderLayout.SOUTH);
button1.addActionListener(new ActionListener() {
private List<Color> colors = new ArrayList<>();
private int freq = 0;
#Override
public void actionPerformed(ActionEvent e) {
sinusPane.addSinusPlot(generateSinus(++freq, nextColor()));
sinusPane.addSinusPlot(generateSinus(++freq, nextColor()));
sinusPane.addSinusPlot(generateSinus(++freq, nextColor()));
}
protected Color nextColor() {
if (colors.isEmpty()) {
colors.addAll(Arrays.asList(masterColors));
Collections.shuffle(colors);
}
return colors.remove(0);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private Random rnd = new Random();
private SinusPlot generateSinus(int freq, Color color) {
double[] x = new double[200];
double[] y = new double[200];
for (int i = 0; i < 200; i++) {
x[i] = (double) i;
y[i] = 100 * Math.sin(2d * Math.PI * freq * i / 200d);
}
return new SinusPlot(x, y, color);
}
public class SinusPlot {
private double[] x;
private double[] y;
private Color color;
public SinusPlot(double[] x, double[] y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public int getSize() {
return x.length;
}
public double getXAt(int index) {
return x[index];
}
public double getYAt(int index) {
return y[index];
}
public Color getColor() {
return color;
}
}
public class TestDrawSinus extends JPanel {
private List<SinusPlot> plots = new ArrayList<>(8);
public void addSinusPlot(SinusPlot plot) {
plots.add(plot);
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (SinusPlot plot : plots) {
System.out.println(plot.getColor());
g2d.setColor(plot.getColor());
for (int i = 0; i < plot.getSize(); i++) {
Ellipse2D dot = new Ellipse2D.Double(((getWidth() - plot.getSize()) / 2) + plot.getXAt(i), plot.getYAt(i) + getHeight() / 2, 10, 10);
g2d.fill(dot);
}
}
g2d.dispose();
}
}
}
null layouts aren't going to help you, take the time to learn understand how the layout management system works, it will save you lot of time and effort. See Laying Out Components Within a Container for more details.
static is not your friend (especially in this context), make the effort to understand how to live without it (and when to use it)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
As i've declared in title of my question, I'm about to make a sort of editor of particular areas of a given png image to change colours pixel by pixel by clicking on it, maybe helping myself magnifying the area...
I'm mainly stuck because I don't know, ad I didn't find so far a solution to display a png which has a "grid" that divides every pixel.
I mean, a sort of thin line that like crosswords could "highlight" every pixel.
Pls point me in the right direction!
thanks!
Okay, so basically, what this is does is a very "simple" scaling process. Each pixel in the image is represented by a "cell" which has a size. Each cell is filled with the color of the pixel. A simple grid is then overlaid on top.
You can use the slider to change the scaling (making the grid larger or smaller).
The example also makes use of the tool tip support to show the pixel color
This example doesn't providing editing though. It would be a trival matter to add a MouseListener to the EditorPane and using the same algorithm as the getToolTipText method, find the pixel which needs to be updated.
My example was using a large sprite (177x345) and is intended to provide for a variable sized sprite. Smaller or fixed sized sprites will provide better performance.
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
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 SpriteEditorSpane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class SpriteEditorSpane extends JPanel {
private JLabel sprite;
private JSlider zoom;
private EditorPane editorPane;
public SpriteEditorSpane() throws IOException {
setLayout(new GridBagLayout());
BufferedImage source = ImageIO.read(new File("sprites/Doctor-01.png"));
sprite = new JLabel(new ImageIcon(source));
editorPane = new EditorPane();
editorPane.setSource(source);
zoom = new JSlider(2, 10);
zoom.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
editorPane.setGridSize(zoom.getValue());
}
});
zoom.setValue(2);
zoom.setPaintTicks(true);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = GridBagConstraints.REMAINDER;
add(sprite, gbc);
gbc.gridx++;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
add(new JScrollPane(editorPane), gbc);
gbc.gridy++;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.weighty = 0;
add(zoom, gbc);
}
}
public class EditorPane extends JPanel implements Scrollable {
private BufferedImage source;
private BufferedImage gridBuffer;
private int gridSize = 2;
private Color gridColor;
private Timer updateTimer;
public EditorPane() {
updateTimer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
doBufferUpdate();
revalidate();
repaint();
}
});
updateTimer.setRepeats(false);
addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
updateBuffer();
}
});
setGridColor(new Color(128, 128, 128, 128));
setToolTipText("Sprite");
}
#Override
public Dimension getPreferredSize() {
return source == null ? new Dimension(200, 200)
: new Dimension(source.getWidth() * gridSize, source.getHeight() * gridSize);
}
public void setGridColor(Color color) {
if (color != gridColor) {
this.gridColor = color;
updateBuffer();
}
}
public Color getGridColor() {
return gridColor;
}
public void setSource(BufferedImage image) {
if (image != source) {
this.source = image;
updateBuffer();
}
}
public void setGridSize(int size) {
if (size != gridSize) {
this.gridSize = size;
updateBuffer();
}
}
public BufferedImage getSource() {
return source;
}
public int getGridSize() {
return gridSize;
}
#Override
public String getToolTipText(MouseEvent event) {
Point p = event.getPoint();
int x = p.x / getGridSize();
int y = p.y / getGridSize();
BufferedImage source = getSource();
String tip = null;
if (x < source.getWidth() && y < source.getHeight()) {
Color pixel = new Color(source.getRGB(x, y), true);
StringBuilder sb = new StringBuilder(128);
sb.append("<html><table><tr><td>");
sb.append("R:").append(pixel.getRed());
sb.append(" G:").append(pixel.getGreen());
sb.append(" B:").append(pixel.getBlue());
sb.append(" A:").append(pixel.getAlpha());
String hex = String.format("#%02x%02x%02x%02x", pixel.getRed(), pixel.getGreen(), pixel.getBlue(), pixel.getAlpha());
sb.append("</td></tr><tr><td bgcolor=").append(hex);
sb.append("width=20 height=20> </td></tr></table>");
tip = sb.toString();
}
return tip;
}
#Override
public Point getToolTipLocation(MouseEvent event) {
Point p = new Point(event.getPoint());
p.x += 8;
p.y += 8;
return p;
}
protected void doBufferUpdate() {
BufferedImage source = getSource();
int gridSize = getGridSize();
gridBuffer = null;
if (source != null) {
gridBuffer = new BufferedImage(source.getWidth() * gridSize, source.getHeight() * gridSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = gridBuffer.createGraphics();
for (int row = 0; row < source.getHeight(); row++) {
for (int col = 0; col < source.getWidth(); col++) {
int xPos = col * gridSize;
int yPos = row * gridSize;
Color pixel = new Color(source.getRGB(col, row), true);
g2d.setColor(pixel);
g2d.fillRect(xPos, yPos, gridSize, gridSize);
g2d.setColor(getGridColor());
g2d.drawRect(xPos, yPos, gridSize, gridSize);
}
}
g2d.dispose();
} else if (getWidth() > 0 && getHeight() > 0) {
gridBuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = gridBuffer.createGraphics();
g2d.setColor(gridColor);
for (int xPos = 0; xPos < getWidth(); xPos += gridSize) {
g2d.drawLine(xPos, 0, xPos, getHeight());
}
for (int yPos = 0; yPos < getHeight(); yPos += gridSize) {
g2d.drawLine(0, yPos, getWidth(), yPos);
}
g2d.dispose();
}
}
protected void updateBuffer() {
updateTimer.restart();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (gridBuffer != null) {
g2d.drawImage(gridBuffer, 0, 0, this);
}
g2d.dispose();
}
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(200, 200);
}
#Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
#Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
#Override
public boolean getScrollableTracksViewportWidth() {
Container parent = getParent();
return parent instanceof JViewport
&& parent.getWidth() > getPreferredSize().width;
}
#Override
public boolean getScrollableTracksViewportHeight() {
Container parent = getParent();
return parent instanceof JViewport
&& parent.getHeight() > getPreferredSize().height;
}
}
}
The overall performance is pretty slow when generating the "grid", you might be able to use byte[] bytes = ((DataBufferByte)gridBuffer.getRaster().getDataBuffer()).getData() which will give you a byte array of the pixels, but in my testing, it didn't make that big a difference.
You might also like to have a look at Zoom box for area around mouse location on screen
I tried to implement the example for a custom TableCellRenderer from here (I tried other examples, too). Whatever I did, my custom TableCellRenderer had absolutely no effect, so I think I'm doing something wrong on a different level. Could anyone please explain to me what exactly I'm doing wrong? Here's my code:
import java.text.DecimalFormat;
import java.util.Random;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
public class Test {
public static void main(String[] args) {
// Show GUI
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GUI gui = new GUI();
int numRows = 5;
int numCols = 5;
DefaultTableModel tableModel = new DefaultTableModel(0,
numCols);
// Add rows
for (int i = 0; i < numRows; i++) {
Float[] row = new Float[numCols];
// Build columns
for (int j = 0; j < numCols; j++) {
Random random = new Random();
row[j] = random.nextFloat();
}
tableModel.addRow(row);
}
JTable table = new JTable(tableModel);
table.setDefaultRenderer(Float.class, new DecRenderer(
new DecimalFormat("##")));
JScrollPane scrollPane = new JScrollPane(table);
gui.getContentPane()
.add(scrollPane, BorderLayout.CENTER);
}
});
}
}
class GUI extends JFrame {
private static final long serialVersionUID = 1L;
public GUI() {
setTitle("GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 400);
setLocationRelativeTo(null);
setVisible(true);
JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(10, 10, 10, 10));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
}
}
// Source: https://stackoverflow.com/questions/2833482/
// how-to-represent-double-values-as-circles-in-a-2d-matrix-in-java/
// 2834484#2834484
#SuppressWarnings("serial")
class DecRenderer extends DefaultTableCellRenderer implements
Icon {
private static final int SIZE = 32;
private static final int HALF = SIZE / 2;
DecimalFormat df;
public DecRenderer(DecimalFormat df) {
this.df = df;
this.setIcon(this);
this.setHorizontalAlignment(SwingConstants.RIGHT);
this.setBackground(Color.lightGray);
}
#Override
protected void setValue(Object value) {
setText((value == null) ? "" : df.format(value));
}
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.blue);
double v = Double.valueOf(this.getText());
int d = (int) (v * SIZE);
int r = d / 2;
g2d.fillOval(x + HALF - r, y + HALF - r, d, d);
}
#Override
public int getIconWidth() {
return SIZE;
}
#Override
public int getIconHeight() {
return SIZE;
}
}
That happens because DefaultTableModel in getColumnClass returns Object.class for all your columns(in your case).
Quick fix is change model like next:
DefaultTableModel tableModel = new DefaultTableModel(0,numCols) {
#Override
public Class<?> getColumnClass(int columnIndex) {
return Float.class;
}
};
add this api in your DecRenderer Class. I have not tested the code, so please resolve some variable compilation errors.
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
return new JPanel() {
#Override
public void paintComponent(Component c, Graphics g, int x, int y) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.blue);
double v = Double.valueOf(DecRenderer.this.getText());
int d = (int) (v * SIZE);
int r = d / 2;
g2d.fillOval(x + HALF - r, y + HALF - r, d, d);
}
}
}
Object fileButton = null;
if("Analyze Text File".equals(command)) {
JFileChooser filechooser;
JFileChooser chooser = new JFileChooser();
int returnVal = filechooser.showOpenDialog(getParent());
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = filechooser.getSelectedFile();
String Stext = (String) readFileAsString(file); //String text = textInput.getText();
Map<Integer, Integer> counts = getCounts(text);
int width = counts.size() * BAR_WIDTH;
int max = maxCount(counts);
int height = max * INCREMENT + 100;
int horizon = height - 25;
HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
//panel.setBorder(new LineBorder(Color.BLACK, 2));
JOptionPane.showMessageDialog(null, panel);
i am creating a java applet where it counts the frequency/occurence of X words, i have worked out how to do the array to work out the frequency depending on what the user inputs, i need to now create a bar chart that adapts to whatever the user inputs, i have wrote up a code for my bar chart but i dont know how to connect it to my array code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.URL;
import java.io.*;
import java.util.HashMap;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Map;
import javax.swing.SwingUtilities;
import javax.swing.JOptionPane;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class assignment_work extends JApplet implements ActionListener {
JTextArea textInput; // User Input.
JLabel wordCountLabel; // To display number of words.
JLabel meanLabel; // To display the mean.
public void init() {
// This code from here is the customisation of the Applet, this includes background colour, text colour, text back ground colour, labels and buttons
setBackground(Color.black);
getContentPane().setBackground(Color.black);
textInput = new JTextArea();
textInput.setWrapStyleWord(true);
JPanel ui = new JPanel();
ui.setLayout(Layout(-1));
/* Creating Analyze and Reset buttons */
JButton chartButton = new JButton("Bar Chart");
chartButton.addActionListener(this);
ui.add(chartButton);
JPanel panel = new JPanel(new BorderLayout())
//panel.add(chartButton, BorderLayout.SOUTH);
/* Labels telling the user what to do or what the program is outputting */
wordCountLabel.setBackground(Color.black);
wordCountLabel.setForeground(Color.red);
wordCountLabel.setOpaque(true);
meanLabel.setBackground(Color.white);
meanLabel.setForeground(Color.black);
meanLabel.setOpaque(true);
watermark.setLayout(new BorderLayout());
watermark.setBackground(Color.darkGray);
/* Border for Applet. */
getContentPane().setLayout( new BorderLayout());
getContentPane().add(ui, BorderLayout.CENTER);
/* Scroll bar for the text area where the user will input the text they wish to analyse. */
JScrollPane scroller = new JScrollPane( textInput );
getContentPane().add(scroller, BorderLayout.CENTER);
getContentPane().add(ui, BorderLayout.NORTH);
}
class CustomCanvas extends Canvas {
public CustomCanvas() {
setBackground(Color.darkGray);
setPreferredSize(new Dimension(100, 100));
}
public void paint(Graphics g) {
int x [] = {20,20,10,10,40,40,30,30};
int y [] = {40,20,20,10,10,20,20,40};
int n = 8;
g.setColor(Color.black);
g.fillPolygon(x,y,n);
int wpoint [] = {45,65,85,75,70,60,55};
int zpoint [] = {40,10,40,40,30,30,40};
int npoint = 7;
g.setColor(Color.black);
g.fillPolygon(wpoint,zpoint,npoint);
int a [] = {60,65,70};
int b [] = {25,20,25};
int npoints = 3;
g.setColor(Color.darkGray);
g.fillPolygon(a,b,npoints);
}
}
private int maxCount(Map<Integer, Integer> counts) {
counts.values()) {
if (num > max) {
max = num;
}
}
return max;
}
public class Panel extends JPanel {
int width;
Map<Integer> count;
public Histogram(int width, Map<Integer, Integer> counts, int horizon) {
this.width = width;
this.dimHeight = dimHeight;
this.horizon = horizon;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 10;
for (Map.Entry<Int> entry : counts.entrySet()) {
int height = entry.getValue() * INCREMENT;
int y = horizon - height;
g.drawString(entry.getValue() + " Frequency", x, y -2);
x += BAR_WIDTH;
}
}
public Dimension getPreferredSize() {
return new Dimension(width, dimHeight);
}
}
public static Map<Int> getCounts(String Input) {
Map<Integer> map = new HashMap<Int>();
String[] array = Input.split("[\\s.,;:!?()");
for (String array) {
Int size;
if (!map(size)) {
map.put(size, 1);
} else {
map.put(map.get(size) + 1);
}
}
return;
}
// Text analysis end
public void actionPerformed(java.awt.event.ActionEvent e) {
if (command.equals("commands")) {
{
final graph<Int> Lengths = new graph<Int>();
String array = Input.Text().split(");
for (int i = 10; i < array.length; i) {
final int Length = array[0].length();
if( Length.Set().container(Length ) ) {
Integer currentNumberOfOccurences = wordLengths.get(wordLength);
currentNumberOfOccurences;
wordLengths.put(wordLength, currentNumberOfOccurences);
}
wordLengths.put(wordLength, 1);
}
double total =10;
double total = 10;
for (final Int length : Lengths.Set()) {
final Int occurrences = Lengths.get(length);
Length = tLength + (length * occurrencers );
totalOccurrences += occurrences;
}
final mean = aLength / lOccurrences;
aLabel.Text("mean word length is: " + (eLength / wOccurrences) );
// System.out.println("mean word length is: " + (total / length) );
}
String array = textInput.getText().split(" ");
int maxWordLength = 0;
wordLength = array[i].length();
if (wordLength > maxWordLength) {
maxWordLength = wordLength;
}
int[] intArray = new int[maxWordLength + 1];
for (int i = 0; i < array.length; i++) {
intArray[array[i].length()]++;
}
for (int i = 1; i < intArray.length; i++) {
out.printf("%d word(s) of length %d<br>", intArray[i], i)
}
else if (command.equals("Reset")) {
textInput.setText("");
textInput.requestFocus();
}
Object chartButton = null;
if (e.getSource() == chartButton) {
String text = textInput.getText();
HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
//panel.setBorder(new LineBorder(Color.BLACK, 2));
JOptionPane.showMessageDialog(null, panel);
}
};
}
Update
Using JFileCHooser
private String readFileAsString(String filePath) throws IOException {
StringBuffer fileData = new StringBuffer();
BufferedReader reader = new BufferedReader(
new FileReader(filePath));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
return fileData.toString();
}
Here's what you want to do to create the dynamic size from the input.
You need to get the number of entries in the map, then multiply it by whatever you want the width of each bar to be.
You need to get the highest value in the map and multiply that by you increment (to draw) amount and create the height from that.
You create a new JPanel with dimension based on the height and width from the previous two points.
Iterate through the map the draw the bars.
I do the things above in the actionPerformed of a button and I add the JPanel to a JOptionPane. Let me know if you need clarification on anything.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class Histogram {
private static final int BAR_WIDTH = 50;
private static final int INCREMENT = 10;
public Histogram() {
final JTextArea textArea = new JTextArea(5, 40);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JButton go = new JButton("Histogram-me!");
JPanel panel = new JPanel(new BorderLayout());
panel.add(textArea, BorderLayout.CENTER);
panel.add(go, BorderLayout.SOUTH);
JFrame frame = new JFrame();
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text = textArea.getText();
Map<Integer, Integer> counts = getCounts(text);
int width = counts.size() * BAR_WIDTH;
int max = maxCount(counts);
int height = max * INCREMENT + 100;
int horizon = height - 25;
HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
//panel.setBorder(new LineBorder(Color.BLACK, 2));
JOptionPane.showMessageDialog(null, panel);
}
});
}
private int maxCount(Map<Integer, Integer> counts) {
int max = 0;
for (Integer num : counts.values()) {
if (num > max) {
max = num;
}
}
return max;
}
public class HistogramPanel extends JPanel {
int width;
int dimHeight;
int horizon;
Map<Integer, Integer> counts;
public HistogramPanel(int width, Map<Integer, Integer> counts, int dimHeight, int horizon) {
this.width = width;
this.counts = counts;
this.dimHeight = dimHeight;
this.horizon = horizon;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 10;
for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
int height = entry.getValue() * INCREMENT;
int y = horizon - height;
g.fillRect(x, y, BAR_WIDTH - 10, height);
g.drawString(entry.getKey() + " chars", x, horizon + 10);
g.drawString(entry.getValue() + " times", x, y -2);
x += BAR_WIDTH;
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, dimHeight);
}
}
public static Map<Integer, Integer> getCounts(String input) {
Map<Integer, Integer> map = new HashMap<>();
String[] array = input.split("[\\s.,;:!?(){}]+");
for (String s : array) {
Integer size = s.length();
if (!map.containsKey(size)) {
map.put(size, 1);
} else {
map.put(size, map.get(size) + 1);
}
}
return map;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Histogram histogram = new Histogram();
}
});
}
}
I have a 2d array of Grids (JPanels) that are added to another JPanel using the GridLayout. That JPanel is added to the JFrame. Whenever a click happens on the JFrame I'm attempting to take the Point of the click and determine if any of those Grids in the 2d array contain that Point.
I'm attempting to do this inside frame.addMouseListener...
I know the frame is registering the mouse clicks. For some reason the Grids don't register that they should be containing that Point. Can anyone explain this? if(theView[i][j].contains(me.getPoint())){ This is the line of code that seems to be failing me.
I originally attempted to have the Grids know when they were clicked on so I wouldn't have to coordinate between the frame and grids, but I couldn't get that to work.
Here's the level designer.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import javax.swing.*;
public class LevelDesigner extends JPanel implements ButtonListener{
private final int SIZE = 12;
private int [][] thePit;
private Grid [][] theView;
private ButtonPanel bp;
public static int val;
private int rows, cols;
private JPanel gridPanel;
private JFrame frame;
public LevelDesigner(int r, int c){
frame = new JFrame();
int h = 10, w = 10;
setVisible(true);
setLayout(new BorderLayout());
setBackground(Color.BLUE);
rows = r;
cols = c;
thePit = new int[r][c];
theView = new Grid[r][c];
gridPanel = new JPanel();
gridPanel.setVisible(true);
gridPanel.setBackground(Color.BLACK);
gridPanel.setPreferredSize(getMaximumSize());
GridLayout gridLayout = new GridLayout();
gridLayout.setColumns(cols);
gridLayout.setRows(rows);
gridPanel.setLayout(gridLayout);
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
theView[i][j] = new Grid(i, j, SIZE, this);
gridPanel.add(theView[i][j]);
}
}
String test [] = {"0", "1","2","3","4","save"};
bp = new ButtonPanel(test, this);
this.add(bp, BorderLayout.SOUTH);
this.add(gridPanel, BorderLayout.CENTER);
frame.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me) {
for(int i = 0; i < rows; ++i){
for(int j = 0; j < cols; ++j){
if(theView[i][j].contains(me.getPoint())){
theView[i][j].actionPerformed(null);
return;
}
}
}
}
});
frame.setVisible(true);
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
frame.setTitle("Epic Crawl - Main Menu");
frame.pack();
frame.setLocationRelativeTo(null);
frame.repaint();
frame.add(this);
}
public String toString(){
int noRows = thePit.length;
int noColumns = thePit[0].length;
String s="";
for (int r=0;r<noRows;r++){
for (int c=0;c<noColumns;c++){
s=s + thePit[r][c] + " ";
}
s=s+"\n";
}
return(s);
}
public void notify( int i, int j){
thePit[i][j] = val;
}
public void print(){
final JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new java.io.File("."));
int returnVal = fc.showSaveDialog( null);
if( returnVal == JFileChooser.APPROVE_OPTION ){
try{
PrintWriter p = new PrintWriter(
new File( fc.getSelectedFile().getName() ) );
System.out.println(" printing");
p.println( this );
p.close();
}
catch( Exception e){
System.out.println("ERROR: file not saved");
}
}
}
public void buttonPressed(String buttonLabel, int id){
if(id == 5)
print();
else
val = id;
}
public void buttonReleased( String buttonLabel, int buttonId ){}
public void buttonClicked( String buttonLabel, int buttonId ){}
public static void main(String arg[]){
LevelDesigner levelDesigner = new LevelDesigner(4, 4);
}
}
And here is the Grid.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Grid extends JPanel implements ActionListener{
LevelDesigner grid;
int myI, myJ;
private String[] imageNames = {"dirt.png", "grass.png", "Door.png", "woodfloor.png", "32x32WoodFloor.png"};
BufferedImage gridImage;
private String imagePath;
public Grid(int i, int j, int size, LevelDesigner m){
imagePath = "";
grid = m;
myI = i;
myJ = j;
setBackground(Color.RED);
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae){
grid.notify(myI, myJ);
imagePath = "Images/" + imageNames[LevelDesigner.val];
gridImage = null;
InputStream input = this.getClass().getClassLoader().getResourceAsStream(imagePath);
try{
gridImage = ImageIO.read(input);
}catch(Exception e){System.err.println("Failed to load image");}
}
public void paintComponent(Graphics g){
super.paintComponent(g); // Important to call super class method
g.clearRect(0, 0, getWidth(), getHeight()); // Clear the board
g.drawImage(gridImage, 0, 0, getWidth(), getHeight(), null);
}
}
The contains method checks if the Point is within the boundaries of the JPanel but using a coordinate system relative to the JPanel. Instead consider using findComponentAt(Point p).
For example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TestMouseListener {
private static final int SIDE_COUNT = 4;
private JPanel mainPanel = new JPanel();
private MyGridCell[][] grid = new MyGridCell[SIDE_COUNT][SIDE_COUNT];
public TestMouseListener() {
mainPanel.setLayout(new GridLayout(SIDE_COUNT, SIDE_COUNT));
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = new MyGridCell();
mainPanel.add(grid[i][j].getMainComponent());
}
}
mainPanel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Component c = mainPanel.findComponentAt(p);
for (MyGridCell[] gridRow : grid) {
for (MyGridCell myGridCell : gridRow) {
if (c == myGridCell.getMainComponent()) {
myGridCell.setLabelText("Pressed!");
} else {
myGridCell.setLabelText("");
}
}
}
}
});
}
public Component getMainComponent() {
return mainPanel;
}
private static void createAndShowGui() {
TestMouseListener mainPanel = new TestMouseListener();
JFrame frame = new JFrame("TestMouseListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyGridCell {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
#SuppressWarnings("serial")
private JPanel mainPanel = new JPanel() {
public Dimension getPreferredSize() {
return MyGridCell.this.getPreferredSize();
};
};
private JLabel label = new JLabel();
public MyGridCell() {
mainPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainPanel.setLayout(new GridBagLayout());
mainPanel.add(label);
}
public Component getMainComponent() {
return mainPanel;
}
public void setLabelText(String text) {
label.setText(text);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
Component#contains "Checks whether this component "contains" the specified point, where the point's x and y coordinates are defined to be relative to the coordinate system of this component"
This means that the contains will only return true if the Point is within the bounds of 0 x 0 x width x height.
So if the component is position at 400x200 and is sized at 200x200 (for example). When you click within in, the mouse point will be between 400x200 and 600x400, which is actually out side of the relative position of the component (200x200) - confused yet...
Basically, you either need to convert the click point to a relative coordinate within the context of the component you are checking...
Point p = SwingUtilities.convertPoint(frame, me.getPoint(), theView[i][j])
if (theView[i][j].contains(p)) {...
Or use the components Rectangle bounds...
if (theView[i][j].getBounds().contains(me.getPoint())) {...
So, remember, mouse events are relative to the component that they were generated for