I have seen this examlpe in a book , and is working fine but the only problem coming up is that the Background Does not turns black on First Call to Paint, When clearCounter become == 5, and then the screen is Cleared and again when Painting Starts, then the Background is turned Black.
public class apletprg extends JApplet implements ActionListener
{
int clearCounter;
Timer t;
public void init(){
setBackground(Color.black);
clearCounter = 0;
Timer t = new Timer(1000, this);
t.start();
}
public void paint(Graphics g)
{
setBackground(Color.black);
clearCounter++;
Graphics2D g2 = (Graphics2D) g;
if (clearCounter == 5){
g2.clearRect(0, 0, 500, 400);
clearCounter=0;
}
for (int i = 1; i <= 40; i++) {
Color c = chooseColor();
g2.setColor(c);
Font f = chooseFont();
g2.setFont(f);
drawJava(g2);
}
}
public void actionPerformed(ActionEvent ae){
repaint();
}
public Color chooseColor(){
int r= (int) (Math.random() * 255);
int g= (int) (Math.random() * 255);
int b= (int) (Math.random() * 255);
Color c = new Color(r,g,b);
return c;
}
public Font chooseFont(){
int fontChoice = (int) (Math.random() * 4) + 1;
Font f = null;
switch (fontChoice) {
case 1: f = new Font("Serif", Font.BOLD + Font.ITALIC, 20);break;
case 2: f = new Font("SansSerif", Font.PLAIN, 17);break;
case 3: f = new Font("Monospaced", Font.ITALIC, 23);break;
case 4: f = new Font("Dialog", Font.ITALIC, 30);break;
}
return f;
}
public void drawJava(Graphics2D g2){
int x = (int) (Math.random() * 500);
int y = (int) (Math.random() * 400);
g2.drawString("Adnan", x, y);
}
}
I Know that the Init () is called only once at the Start , but Why is that not able to change the Background at start?
In your init method replace setBackground(Color.black) with getContentPane().setBackground(Color.black)
And add super.paint(g) as the first line in your paint method.
Otherwise if you don't want to use Swing features then go ahead and import java.applet.Applet and make you class extend Applet instead of JApplet
public class NewClass extends JApplet implements ActionListener {
int clearCounter;
Timer t;
public void init() {
getContentPane().setBackground(Color.black);
repaint();
clearCounter = 0;
//t = new Timer("1000", true);
}
public void paint(Graphics g) {
super.paint(g);
setBackground(Color.black);
clearCounter++;
Graphics2D g2 = (Graphics2D) g;
if (clearCounter == 5) {
g2.clearRect(0, 0, 500, 400);
clearCounter = 0;
}
for (int i = 1; i <= 40; i++) {
Color c = chooseColor();
g2.setColor(c);
Font f = chooseFont();
g2.setFont(f);
drawJava(g2);
}
}
#Override
public void actionPerformed(ActionEvent ae) {
repaint();
}
public Color chooseColor() {
int r = (int) (Math.random() * 255);
int g = (int) (Math.random() * 255);
int b = (int) (Math.random() * 255);
Color c = new Color(r, g, b);
return c;
}
public Font chooseFont() {
int fontChoice = (int) (Math.random() * 4) + 1;
Font f = null;
switch (fontChoice) {
case 1:
f = new Font("Serif", Font.BOLD + Font.ITALIC, 20);
break;
case 2:
f = new Font("SansSerif", Font.PLAIN, 17);
break;
case 3:
f = new Font("Monospaced", Font.ITALIC, 23);
break;
case 4:
f = new Font("Dialog", Font.ITALIC, 30);
break;
}
return f;
}
public void drawJava(Graphics2D g2) {
int x = (int) (Math.random() * 500);
int y = (int) (Math.random() * 400);
g2.drawString("Adnan", x, y);
}
}
If you want to execute super.paint() only once add a boolean variable in your class
boolean firstTime = true;
In paint()
if(firstTime) {
super.paint(g);
firstTime = false;
}
Resolved the ProbleBy Just Adding One more Variable and Calling the ClearRect() at the Start of painting and to ensure that This will be Called only once , by the Help of Newly Added Variable.
public void init(){
setBackground(Color.black);
clearCounter = 0;
Timer t = new Timer(1000, this);
t.start();
check = 0; <------------ New Variable
}
public void paint(Graphics g)
{
if (check==0){
g.clearRect(0, 0, 500, 400); <------------ To Ensure That it will Excute Only Once , beacuse check is incremented later in Code
}
clearCounter++;
check++;
Graphics2D g2 = (Graphics2D) g;
if (clearCounter == 5){
g2.clearRect(0, 0, 500, 400);
clearCounter=0;
}
for (int i = 1; i <= 40; i++) {
Color c = chooseColor();
g2.setColor(c);
Font f = chooseFont();
g2.setFont(f);
drawJava(g2);
}
}
Related
How can I use repaint here, that it changes the display after some interval, like an animation?
Ouput:
(Like initially and randomly it is) this-1 (after some short interval and randomly it changes to) this-2 and continued...
import java.awt.*;
import java.util.Random;
import javax.swing.*;
class MatrixPanel extends JPanel {
private final int sqW = 15;
private final int sqH = 15;
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
#Override
public void paintComponent(Graphics g) {
Random rand = new Random();
for (int i = 0; i < 300; i += this.sqW) {
for (int j = 0; j < 300; j += this.sqH) {
if (rand.nextInt(2) == 1) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.GRAY);
}
g.fillRect(i, j, this.sqW, this.sqH);
g.setColor(Color.BLACK);
g.drawRect(i, j, this.sqW, this.sqH);
}
}
}
}
class GameOfLifeGUI extends JFrame {
public GameOfLifeGUI() {
JSplitPane splitPane = new JSplitPane();
/*Panels*/
JPanel topPanel = new JPanel();
JPanel bottomPanel = new JPanel();
/*Label - 1*/
JLabel generationLabel = new JLabel("GenerationLabel");
generationLabel.setText("Generation #");
generationLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
generationLabel.setBounds(10, 5, 300, 20);
/*Label - 2*/
JLabel aliveLabel = new JLabel("AliveLabel");
aliveLabel.setText("Alive: ");
aliveLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
aliveLabel.setBounds(10, 25, 300, 20);
topPanel.setLayout(null);
topPanel.add(generationLabel);
topPanel.add(aliveLabel);
bottomPanel.add(new MatrixPanel());
setPreferredSize(new Dimension(315, 405));
getContentPane().setLayout(new GridLayout());
getContentPane().add(splitPane);
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
splitPane.setDividerLocation(50);
splitPane.setTopComponent(topPanel);
splitPane.setBottomComponent(bottomPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
pack();
}
public static void main(String[] args) {
new GameOfLifeGUI().setVisible(true);
}
}
Specifically not repaint, if there are other components that I can use and meet my requirements will be most welcome.
Thank you.
You don't want to do the following:
public void paintComponent(Graphics g) {
Random rand = new Random();
for (int i = 0; i < 300; i += this.sqW) {
for (int j = 0; j < 300; j += this.sqH) {
if (rand.nextInt(2) == 1) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.GRAY);
}
g.fillRect(i, j, this.sqW, this.sqH);
g.setColor(Color.BLACK);
g.drawRect(i, j, this.sqW, this.sqH);
}
}
}
Since painting is done on the EDT, you need to keep your processing to a minimum, otherwise performance will suffer and you may even lock up your application.
Use a Swing timer and create the image in a BufferedImage object. BufferedImages provide a graphics context so you can use the same methods you are using in paintComponent.
You can set the timer interval to whatever works for you and then issue a repaint when the image is created. So it could look similar to the following:
final BufferedImage image = new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
...
Timer timer = new Timer(0, ae->createImage());
timer.setDelay(300);
timer.start();
...
public void createImage(BufferedImage image) {
Random rand = new Random();
Graphics g = image.getGraphics();
for (int i = 0; i < 300; i += this.sqW) {
for (int j = 0; j < 300; j += this.sqH) {
if (rand.nextInt(2) == 1) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.GRAY);
}
g.fillRect(i, j, this.sqW, this.sqH);
g.setColor(Color.BLACK);
g.drawRect(i, j, this.sqW, this.sqH);
}
}
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Image observer not required so it can be set to null.
g.drawImage(image, 0,0, null);
}
Finally, you need to set your MatrixPanel size large enough to hold the image. Probably 300 x 300.
When you click in a box, it should create a circle in that box from the designated coordinate. Unless if its already there then its removed. How do I get currentx and currenty coordinates into the fill oval?
public class Grid extends Applet{
boolean click;
public void init()
{
click = false;
addMouseListener(new MyMouseListener());
}
public void paint(Graphics g)
{
super.paint(g);
g.drawRect(100, 100, 400, 400);
//each box
g.drawRect(100, 100, 100, 100);
g.drawRect(200, 100, 100, 100);
g.drawRect(300, 100, 100, 100);
g.drawRect(400, 100, 100, 100);
//2y
g.drawRect(100, 200, 100, 100);
g.drawRect(200, 200, 100, 100);
g.drawRect(300, 200, 100, 100);
g.drawRect(400, 200, 100, 100);
//3y1x
g.drawRect(100, 300, 100, 100);
g.drawRect(200, 300, 100, 100);
g.drawRect(300, 300, 100, 100);
g.drawRect(400, 300, 100, 100);
//4y1x
g.drawRect(100, 400, 100, 100);
g.drawRect(200, 400, 100, 100);
g.drawRect(300, 400, 100, 100);
g.drawRect(400, 400, 100, 100);
if (click)
{
g.fillOval(currentx, currenty, 100, 100); // problem HERE
}
}
private class MyMouseListener implements MouseListener
{
public void mouseClicked(MouseEvent e)
{
int nowx = e.getX();
int nowy = e.getY();
nowx = nowx / 100;
String stringx = Integer.toString(nowx);
stringx = stringx+"00";
int currentx = Integer.parseInt(stringx);
nowy = nowy /100;
String stringy = Integer.toString(nowy);
stringy = stringy+"00";
int currenty = Integer.parseInt(stringy);
click = true;
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}
Your main problem is, painting in Swing/AWT is destructive, that is, each time your paint method is called, you are expected to repaint the current state of the component.
In that case, what you really need is some way to model the state of the game so when paint is called, you can repaint it in some meaningful way. This a basic concept of a Model-View-Controller paradigm, where you separate the responsibility of the program into separate layers.
The problem then becomes, how do you translate from the view to model?
The basic idea is take the current x/y coordinates of the mouse and divide it by the cell size. You also need to ensure that the results are within the expected ranges, as you could get a result which is beyond the columns/rows of grids
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
protected static final int CELL_COUNT = 3;
private int[][] board;
private int[] cell;
private boolean isX = true;
public TestPane() {
board = new int[CELL_COUNT][CELL_COUNT];
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
int[] cell = getCellAt(e.getPoint());
if (board[cell[0]][cell[1]] == 0) {
board[cell[0]][cell[1]] = isX ? 1 : 2;
isX = !isX;
repaint();
}
}
});
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
cell = getCellAt(e.getPoint());
repaint();
}
});
}
protected int[] getCellAt(Point p) {
Point offset = getOffset();
int cellSize = getCellSize();
int x = p.x - offset.x;
int y = p.y - offset.y;
int gridx = Math.min(Math.max(0, x / cellSize), CELL_COUNT - 1);
int gridy = Math.min(Math.max(0, y / cellSize), CELL_COUNT - 1);
return new int[]{gridx, gridy};
}
protected Point getOffset() {
int cellSize = getCellSize();
int x = (getWidth() - (cellSize * CELL_COUNT)) / 2;
int y = (getHeight() - (cellSize * CELL_COUNT)) / 2;
return new Point(x, y);
}
protected int getCellSize() {
return Math.min(getWidth() / CELL_COUNT, getHeight() / CELL_COUNT) - 10;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Point offset = getOffset();
int cellSize = getCellSize();
if (cell != null) {
g2d.setColor(new Color(0, 0, 255, 128));
g2d.fillRect(
offset.x + (cellSize * cell[0]),
offset.y + (cellSize * cell[1]),
cellSize,
cellSize);
}
g2d.setColor(Color.BLACK);
FontMetrics fm = g2d.getFontMetrics();
for (int col = 0; col < CELL_COUNT; col++) {
for (int row = 0; row < CELL_COUNT; row++) {
int value = board[col][row];
int x = offset.x + (cellSize * col);
int y = offset.y + (cellSize * row);
String text = "";
switch (value) {
case 1:
text = "X";
break;
case 2:
text = "O";
break;
}
x = x + ((cellSize - fm.stringWidth(text)) / 2);
y = y + ((cellSize - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(text, x, y);
}
}
int x = offset.x;
int y = offset.y;
for (int col = 1; col < CELL_COUNT; col++) {
x = offset.x + (col * cellSize);
g2d.drawLine(x, y, x, y + (cellSize * CELL_COUNT));
}
x = offset.x;
for (int row = 1; row < CELL_COUNT; row++) {
y = offset.x + (row * cellSize);
g2d.drawLine(x, y, x + (cellSize * CELL_COUNT), y);
}
g2d.dispose();
}
}
}
First off, if you want to truncate a number to the nearest 100, e.g. 142 becomes 100, all you have to do is:
num = (num/100)*100;
this is because when you divide 2 integers it automatically truncates it, and you can just multiply it back to get the number. And what I think you want in this case is to create some field variables and some accessor methods. At the top of your MouseListener class, you will need to add:
private int mouseX=0;
private int mouseY=0;
then to be able to access these variables from outside of the mouselistener class you will need to add accessor methods:
public int getMouseX(){
return mouseX;
}
in your Grid Class, you can add the field:
private MyMouseListener listener;
and then initialize it in your init by doing:
listener = new MyMouseListener();
addMouseListener(listener);
then you can do the same for mouseY, and finally from your paint method you can then call:
int mouseX = listener.getMouseX();
int mouseY = listener.getMouseY();
and from there it is as simple as doing if statements or switch statements to find which box you clicked in!
I am having problem with the JFrame textfield.
I am trying to make a word game, but the problem is that when I try to create textfield to set an input and then check if it's the right word, I have got the word thing covered.
The problem is that when I try to add Textfield, it disappears when i render things to JFrame.
public teksti() {
setTitle("Hirsipuu");
setSize(leveys,korkeus);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
setLocationRelativeTo(null);
setBackground(Color.white);
jp.add(tf); // adding JtextField (JTextField tf = new JTextField(30);)
add(jp);
}
and my render() is like this (just for testing purpose).
private void render() {
BufferStrategy bs = this.getBufferStrategy(); // tehdään uusi bufferi
if (bs == null) {
createBufferStrategy(3);
return;
}
int R = (int) (Math.random( )*256);
int G = (int)(Math.random( )*256);
int B= (int)(Math.random( )*256);
Color randomColor = new Color(R, G, B);
Graphics g = bs.getDrawGraphics();
g.drawString("Arvaa sana", 100 , 100);
g.setColor(Color.white);
g.fillRect(0, 50, leveys, korkeus);
g.setColor(randomColor);
g.setFont(h);
// g.drawLine(0,0,liikey*2-1,liikex);
for(int i = 0; i < salat.size(); i ++) {
g.drawString(salat.get(i),liikex+rand.nextInt(50),liikey+rand.nextInt(50));
}
System.out.println(liikex + " " + liikey);
g.dispose();
bs.show();
g.dispose();
}
I can get the textfield to be displayed on top at the start, but then it disappears.
Anyone knows if there is a better way to do this?
Don't draw directly in a JFrame
Instead, if you need to draw a background image, do so in the paintComponent method of a JPanel. This will likely work much better than using BufferStrategy for your purposes.
Then you can add components, such as your JTextField to this JPanel.
And then add this JPanel to your JFrame.
Always call the super's paintComponent method in your own paintComponent method override.
Be careful to never dispose of a Graphics object given to you from the JVM, such as the one passed into your paintComponent method.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import javax.swing.*;
public class BackgroundPanel extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 600;
private static final Font PROMPT_FONT = new Font(Font.SANS_SERIF, Font.BOLD,
24);
private Paint gradientPaint;
private JTextField textField = new JTextField(20);
public BackgroundPanel() {
int red = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
Color color1 = new Color(red, green, blue);
red = (int) (Math.random() * 256);
green = (int) (Math.random() * 256);
blue = (int) (Math.random() * 256);
Color color2 = new Color(red, green, blue);
gradientPaint = new GradientPaint(0, 0, color1, 20, 20, color2, true);
JLabel promptLabel = new JLabel("Input:");
promptLabel.setFont(PROMPT_FONT);
add(promptLabel);
add(textField);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(gradientPaint);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.black);
g.setFont(PROMPT_FONT);
g.drawString("Arvaa sana", 100, 100);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
BackgroundPanel mainPanel = new BackgroundPanel();
JFrame frame = new JFrame("BackgroundPanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
this is basically whole thing i got done now.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class teksti extends JFrame implements Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
ArrayList<String> sanat = new ArrayList<String>();
ArrayList<String> salat = new ArrayList<String>();
String dir = System.getProperty("user.dir");
String pathname = dir + "\\src\\kotus_sanat.txt";
Random rand = new Random();
Scanner lukija = new Scanner(System.in);
String syote,salasana,salasana2;
int leveys=500,korkeus=500;
int liikex=300, liikey=300;
Font h = new Font("Helvetica", Font.PLAIN, 18);
JTextField tf = new JTextField(30);
JPanel jp = new JPanel();
JFrame jf = new JFrame();
public teksti() {
setTitle("Hirsipuu");
setSize(leveys,korkeus);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
setLocationRelativeTo(null);
setBackground(Color.white);
jp.add(tf);
add(jp);
}
public static void main(String args[]){
teksti teksti = new teksti();
teksti.start();
}
private void start() {
run();
}
public void run() {
sanat = lataa();
System.out.println(pathname);
System.out.println(sanat.size() + " sanaa ladattu..");
int sanoja=sanat.size();
for (int i = 0; i < 10; i++){
salat.add(sanat.get(rand.nextInt(sanoja)));
}
System.out.println("salasana on " + salasana);
long lastTime = System.nanoTime(); // fps sälää
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
requestFocus();
boolean running=true;
while (running){
long now = System.nanoTime();
delta += (now-lastTime) / ns;
lastTime = now;
while ( delta >= 1) {
update();
updates++;
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
setTitle("Hirsipuu"+ " | " + updates + " ups " + frames + " fps" );
updates = 0;
frames = 0;
}
}
}
private void update() {
liikex = liikex + 1;
liikey= liikey - 4;
if (liikey>korkeus)
liikey = 1;
if (liikex>leveys)
liikex= 1;
if (liikey<20)
liikey = korkeus;
}
private void render() {
BufferStrategy bs = this.getBufferStrategy(); // tehdään uusi bufferi
if (bs == null) {
createBufferStrategy(3);
return;
}
int R = (int) (Math.random( )*256);
int G = (int)(Math.random( )*256);
int B= (int)(Math.random( )*256);
Color randomColor = new Color(R, G, B);
Graphics g = bs.getDrawGraphics();
g.drawString("Arvaa sana", 100 , 100);
g.setColor(Color.white);
g.fillRect(0, 50, leveys, korkeus);
g.setColor(randomColor);
g.setFont(h);
// g.drawLine(0,0,liikey*2-1,liikex);
for(int i = 0; i < salat.size(); i ++) {
g.drawString(salat.get(i), liikex+rand.nextInt(50),liikey+rand.nextInt(50));
}
System.out.println(liikex + " " + liikey);
g.dispose();
bs.show();
g.dispose();
}
private void stop() {
}
private void vertaa() {
System.out.println("Anna sana niin tarkastaan onko se oikea suomenkielinen sana: ");
syote = lukija.next();
boolean oikea = false;
int i = 0;
int z = 0;
while (i < sanat.size()) {
if (syote.equals(sanat.get(i))) {
oikea = true;
System.out.println (syote + " on oikea suomalainen sana.");
break;
}
else{
}
}
if (!oikea) {
System.out.println(syote + " ei ole oikea suomalainen sana.");
}
}
public ArrayList<String> lataa() {
String line = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(pathname));
while((line = reader.readLine()) != null){
sanat.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return sanat;
}
}
vertaa() is not used.
I've tried to run the example found in Java Swing 2nd Edition 7.1.3 ScrollPaneLayout. The image and the scroll have worked just fine, but the ruler hasn't. Here's my code:
public class ScrollPaneLayoutDemo extends JFrame{
JLabel label = new JLabel(new ImageIcon("img.jpg"));
public ScrollPaneLayoutDemo() {
super("ScrollPaneLayout Demo");
JScrollPane jsp = new JScrollPane(label);
JLabel[] corners = new JLabel[4];
for(int i=0; i<4; i++)
{
corners[i] = new JLabel();
corners[i].setBackground(Color.YELLOW);
corners[i].setOpaque(true);
corners[i].setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2), BorderFactory.createLineBorder(Color.RED, 1)));
}
JLabel rowheader = new JLabel() {
Font f = new Font("Serif", Font.ITALIC | Font.BOLD, 10);
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Rectangle r = g.getClipBounds();
g.setFont(f);
g.setColor(Color.RED);
for (int i = 50 - (r.y % 50); i < r.height; i += 50) {
g.drawLine(0, r.y + i, 3, r.y + i);
g.drawString("" + (r.y + i), 6, r.y + i + 3);
}
}
public Dimension getPreferredSize()
{
return new Dimension(25, (int) label.getPreferredSize().getHeight());
}
};
rowheader.setBackground(Color.YELLOW);
rowheader.setOpaque(true);
JLabel columnheader = new JLabel() {
Font f = new Font("Serif", Font.ITALIC | Font.BOLD, 10);
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Rectangle r = g.getClipBounds();
g.setFont(f);
g.setColor(Color.RED);
for (int i = 50 - (r.x % 50); i < r.width; i += 50)
{
g.drawLine(r.x + i, 0, r.x + i, 3);
g.drawString("" + (r.x + i), r.x + i - 10, 16);
}
}
public Dimension getPreferredSize()
{
return new Dimension((int) label.getPreferredSize().getWidth(),25);
}
};
columnheader.setBackground(Color.YELLOW);
columnheader.setOpaque(true);
jsp.setRowHeaderView(rowheader);
jsp.setColumnHeaderView(columnheader);
jsp.setCorner(JScrollPane.LOWER_LEFT_CORNER, corners[0]);
jsp.setCorner(JScrollPane.LOWER_RIGHT_CORNER, corners[1]);
jsp.setCorner(JScrollPane.UPPER_LEFT_CORNER, corners[2]);
jsp.setCorner(JScrollPane.UPPER_RIGHT_CORNER, corners[3]);
getContentPane().add(jsp, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setVisible(true);
}
public static void main(String[] args) {
new JScrollPaneDemo();
}
}
If anyone could help me with this issue I appreciate.
Dimension from child must be greater than JViewports Dimension (visible rectangle from JScrollPane), then JScrollBars or custom decorations can be visible, more in Oracle tutorial How to use ScrollPanes
search for #Annotations
e.g.
no idea why but I can't add image here :-)
from
import java.awt.*;
import javax.swing.*;
public class ScrollPaneLayoutDemo extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel label = new JLabel(new ImageIcon("img.jpg")) {
#Override
public Dimension getPreferredSize() {
return new Dimension(new Dimension(800, 600));/*icon.getIconWidth(), icon.getIconHeight()*/
}
};
public ScrollPaneLayoutDemo() {
super("ScrollPaneLayout Demo");
label.setPreferredSize(new Dimension(800, 600));
JScrollPane jsp = new JScrollPane(label);
JLabel[] corners = new JLabel[4];
for (int i = 0; i < 4; i++) {
corners[i] = new JLabel();
corners[i].setBackground(Color.YELLOW);
corners[i].setOpaque(true);
corners[i].setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2), BorderFactory.createLineBorder(Color.RED, 1)));
}
JLabel rowheader = new JLabel() {
private static final long serialVersionUID = 1L;
Font f = new Font("Serif", Font.ITALIC | Font.BOLD, 10);
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle r = g.getClipBounds();
g.setFont(f);
g.setColor(Color.RED);
for (int i = 50 - (r.y % 50); i < r.height; i += 50) {
g.drawLine(0, r.y + i, 3, r.y + i);
g.drawString("" + (r.y + i), 6, r.y + i + 3);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(25, (int) label.getPreferredSize().getHeight());
}
};
rowheader.setBackground(Color.YELLOW);
rowheader.setOpaque(true);
JLabel columnheader = new JLabel() {
private static final long serialVersionUID = 1L;
Font f = new Font("Serif", Font.ITALIC | Font.BOLD, 10);
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle r = g.getClipBounds();
g.setFont(f);
g.setColor(Color.RED);
for (int i = 50 - (r.x % 50); i < r.width; i += 50) {
g.drawLine(r.x + i, 0, r.x + i, 3);
g.drawString("" + (r.x + i), r.x + i - 10, 16);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension((int) label.getPreferredSize().getWidth(), 25);
}
};
columnheader.setBackground(Color.YELLOW);
columnheader.setOpaque(true);
jsp.setRowHeaderView(rowheader);
jsp.setColumnHeaderView(columnheader);
jsp.setCorner(JScrollPane.LOWER_LEFT_CORNER, corners[0]);
jsp.setCorner(JScrollPane.LOWER_RIGHT_CORNER, corners[1]);
jsp.setCorner(JScrollPane.UPPER_LEFT_CORNER, corners[2]);
jsp.setCorner(JScrollPane.UPPER_RIGHT_CORNER, corners[3]);
getContentPane().add(jsp, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ScrollPaneLayoutDemo();
}
});
}
}
Is there a way to make a JButton which has a transparent fill(30% transparent) and a text which is not transparent?
For now I discovered the following options:
make both the button and the text transparent.
make both of them not transparent.
is there an option in between?
Here is one possible implementation using JButton#setIcon(Icon_30%_transparent):
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
public final class TranslucentButtonIconTest {
private static final TexturePaint TEXTURE = makeCheckerTexture();
public JComponent makeUI() {
JPanel p = new JPanel() {
#Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(TEXTURE);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
};
p.add(makeButton("aaa"));
p.add(makeButton("bbbbbbb"));
p.add(makeButton("ccccccccccc"));
p.add(makeButton("ddddddddddddddddddddddddddddd"));
return p;
}
private static AbstractButton makeButton(String title) {
return new JButton(title) {
#Override public void updateUI() {
super.updateUI();
setVerticalAlignment(SwingConstants.CENTER);
setVerticalTextPosition(SwingConstants.CENTER);
setHorizontalAlignment(SwingConstants.CENTER);
setHorizontalTextPosition(SwingConstants.CENTER);
setBorder(BorderFactory.createEmptyBorder(2, 8, 2, 8));
setMargin(new Insets(2, 8, 2, 8));
setContentAreaFilled(false);
setFocusPainted(false);
setOpaque(false);
setForeground(Color.WHITE);
setIcon(new TranslucentButtonIcon());
}
};
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TranslucentButtonIconTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static TexturePaint makeCheckerTexture() {
int cs = 6;
int sz = cs * cs;
BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setPaint(new Color(120, 120, 220));
g2.fillRect(0, 0, sz, sz);
g2.setPaint(new Color(200, 200, 200, 20));
for (int i = 0; i * cs < sz; i++) {
for (int j = 0; j * cs < sz; j++) {
if ((i + j) % 2 == 0) {
g2.fillRect(i * cs, j * cs, cs, cs);
}
}
}
g2.dispose();
return new TexturePaint(img, new Rectangle(0, 0, sz, sz));
}
}
class TranslucentButtonIcon implements Icon {
private static final int R = 8;
private int width;
private int height;
#Override public void paintIcon(Component c, Graphics g, int x, int y) {
if (c instanceof AbstractButton) {
AbstractButton b = (AbstractButton) c;
Insets i = b.getMargin();
int w = c.getWidth();
int h = c.getHeight();
width = w - i.left - i.right;
height = h - i.top - i.bottom;
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Shape area = new RoundRectangle2D.Float(x - i.left, y - i.top, w - 1, h - 1, R, R);
Color color = new Color(0f, 0f, 0f, .3f);
ButtonModel m = b.getModel();
if (m.isPressed()) {
color = new Color(0f, 0f, 0f, .3f);
} else if (m.isRollover()) {
color = new Color(1f, 1f, 1f, .3f);
}
g2.setPaint(color);
g2.fill(area);
g2.setPaint(Color.WHITE);
g2.draw(area);
g2.dispose();
}
}
#Override public int getIconWidth() {
return Math.max(width, 100);
}
#Override public int getIconHeight() {
return Math.max(height, 24);
}
}