I am making a storybook and, because I'm not very creative with names, I gave images page numbers like so.
ImageIcon pg1icon = new ImageIcon("images/1.png");
ImageIcon pg2icon = new ImageIcon("images/2.png");
ImageIcon pg3icon = new ImageIcon("images/3.png");
JLabel pg1Label = new JLabel(pg1icon);
JLabel pg2Label = new JLabel(pg2icon);
JLabel pg3Label = new JLabel(pg3icon);
Because I have 30 pages, this process is getting tedious. Is there a way to scale the page num similar to i++?
Using streams we can handle this requirement concisely as:
List<JLabel> labels = IntStream.rangeClosed(1, 30)
.mapToObj(i -> new JLabel(new ImageIcon("images/" + i + ".png")))
.collect(Collectors.toList());
Assuming you only need the ImageIcon for the JLabel, you could use one array to store your thirty JLabel(s). Like,
int pageCount = 30;
JLabel[] labels = new JLabel[pageCount];
for (int i = 0; i < pageCount; i++) { // <-- i++ as requested
ImageIcon icon = new ImageIcon(String.format("images/%d.png", 1+i));
labels[i] = new JLabel(icon);
}
And then use labels[0] - labels[29] instead of pg1Label - pg30Label.
Related
At the moment I have a list with images which get displayed for a certain amount of time with a timeline. However I want that a counter is set for each picture i.e. if the amount of time is 30 sec for each picture, there should be a countdown running and showing underneath the picture? Is there a way to achieve that behavior?
Image i1 = new Image(getClass().getResourceAsStream("IMG_YOGA/01.png"),200,200,false,false);
Image i2 = new Image(getClass().getResourceAsStream("IMG_YOGA/02.png"),200,200,false,false);
Image i3 = new Image(getClass().getResourceAsStream("IMG_YOGA/03.png"),200,200,false,false);
Image i4 = new Image(getClass().getResourceAsStream("IMG_YOGA/04.png"),200,200,false,false);
Image i5 = new Image(getClass().getResourceAsStream("IMG_YOGA/05.png"),200,200,false,false);
Image i6 = new Image(getClass().getResourceAsStream("IMG_YOGA/06.png"),200,200,false,false);
Image i7 = new Image(getClass().getResourceAsStream("IMG_YOGA/07.png"),200,200,false,false);
Image i8 = new Image(getClass().getResourceAsStream("IMG_YOGA/08.png"),200,200,false,false);
Y_ImgView.setFitWidth(250);
Y_ImgView.setFitHeight(300);
final int NUM_FRAMES = 9;
final int PAUSE_BETWEEN_FRAMES = 30;
Timeline timeline = new Timeline();
List<Image> images = List.of(i1,i2,i3,i4,i5,i6,i7,i8,i1);
for (int i = 0; i < NUM_FRAMES; i++) {
timeline.getKeyFrames().add(
new KeyFrame(
javafx.util.Duration.seconds(i * PAUSE_BETWEEN_FRAMES),
new KeyValue(Y_ImgView.imageProperty(), images.get(i))
)
);
}
timeline.setCycleCount(1);
timeline.play();
}
Try something like
IntegerProperty countdown = new SimpleIntegerProperty();
Label countdownLabel = new Label();
countdownLabel.textProperty().bind(countdown.asString());
// add label to layout
and then
Timeline timeline = new Timeline();
List<Image> images = List.of(i1,i2,i3,i4,i5,i6,i7,i8,i1);
for (int i = 0; i < NUM_FRAMES; i++) {
timeline.getKeyFrames().add(
new KeyFrame(
javafx.util.Duration.seconds(i * PAUSE_BETWEEN_FRAMES),
new KeyValue(Y_ImgView.imageProperty(), images.get(i)),
new KeyValue(countdown, 0),
new KeyValue(countdown, PAUSE_BETWEEN_FRAMES)
)
);
}
Basically I have made an interface that displays a picture and it has multiple JSliders. Each one has a different function such as blur, brighten, and saturate. I have implemented the sliders in such a way that I override the stateChanged method when adding a new slider. This works fine when I do the sliders individually, however it changes back to the original picture once I use a different slider. I want to make it so that it the picture accumulates the filters on the photo. Any suggestions? Here is an example of one of my sliders.
brightSlider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
double scaleValue = source.getValue() / 100.0;
Picture newPic = new PictureImpl(picture.getWidth(), picture.getHeight());
//Picture newPic = picture;
Pixel zeroPixel = new ColorPixel(0, 0, 0);
Pixel p;
for (int i = 0; i < picture.getWidth(); i++) {
for (int j = 0; j < picture.getHeight(); j++) {
newPic.setPixel(i, j, zeroPixel);
}
}
for (int i = 0; i < picture.getWidth(); i++) {
for (int j = 0; j < picture.getHeight(); j++) {
if (scaleValue > 0) {
p = picture.getPixel(i, j).lighten(scaleValue);
newPic.setPixel(i, j, p);
} else if (scaleValue < 0) {
p = picture.getPixel(i, j).darken(scaleValue);
newPic.setPixel(i, j, p);
}
}
}
setPic(newPic);
picture_view.setPicture(newPic.createObservable());
}
});
As shown in Image processing with Java 2D, you can create a Map<String, BufferedImageOp> that holds concrete instances of the BufferedImageOp interface.
Map<String, BufferedImageOp> ops = new TreeMap<String, BufferedImageOp>();
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ops.put("Gray", new ColorConvertOp(cs, null));
…
Add the Map key set to a JComboBox.
final JComboBox opBox = new JComboBox();
for (String key : ops.keySet()) {
opBox.addItem(key);
}
In the combo's handler, invoke the image operation's filter() method on your target BufferedImage.
String key = (String) opBox.getSelectedItem();
BufferedImageOp op = ops.get(key);
bufferedImage = op.filter(bufferedImage, null);
The image below illustrates "Threshold 64" followed by "Invert". ImageDicer is a complete example.
I'm in the process of creating a frogger type game and have gotten pretty far in getting the program to do what I want it to do. However, I'm starting to think that to finish the game I will have to use way to much code and there must be a simpler way achieve the same results. I'm not looking for an answer, just need some more information.
Question 1: What can I use for the images that represent the moving Icons or cars? I'm currently using JButtons. The problem is that is difficult to get the buttons to move uniformly and I want to use 24 different moving Icons and from what I've learned so far I will have to add a new JButton for each icon.
Question 2: The way that I've gotten the Jbutton icons to move is to use a timer delay and then a counter to increment the x values. This works for the most part, but is there a better, perhaps simpler, way to move icons across the screen?
Any tips, tutorials etc are greatly appreciated.
Here is one of the classes that I've created to get movement of the icons:
public class EnemyJPanel extends JButton {
JButton enem = new JButton();
JButton enem12 = new JButton();
JButton enem13 = new JButton();
JButton enem1 = new JButton("1");
JButton enem2 = new JButton("2");
JButton enem3 = new JButton("3");
JButton enem4 = new JButton("4");
JButton score = new JButton("Score");
JButton enem5 = new JButton("5");
JButton enem6 = new JButton("6");
JButton enem7 = new JButton("7");
JButton enem8 = new JButton("8");
JButton yard = new JButton("50 Yard Line");
int i = 16;
int u = 576;
int d = 16;
int n = 576;
int k = 16;
int l = 16;
int dummyval = 16;
public EnemyJPanel(){
super();
setLayout(null);
enem1.setBounds(16,300,40,55);
enem2.setBounds(16,245,40,55);
enem3.setBounds(16,190,40,55);
enem4.setBounds(16,135,40,55);
score.setBounds(16,80,601,55);
yard.setBounds(16,355,601,55);
enem5.setBounds(16,410,40,55);
enem6.setBounds(16,465,40,55);
enem7.setBounds(16,520,40,55);
enem8.setBounds(16,575,40,55);
enem12.setBounds(16,300,40,55);
enem13.setBounds(16,300,40,55);
add(enem1);
add(enem2);
add(enem3);
add(enem4);
add(score);
}
public void addEnemy(){
enem1.setBounds(16,300,40,55);
enem2.setBounds(16,245,40,55);
enem3.setBounds(16,190,40,55);
enem4.setBounds(16,135,40,55);
score.setBounds(16,80,601,55);
add(enem1);
add(enem2);
add(enem3);
add(enem4);
add(score);
}
public void enemyMovement(){
i++;u--;d++;n--; // increments lateral movement from a timer in
dummyval++; // the dummy value is needed to keep the icons looping
dummyval = dummyval + 2;
enem1.setBounds(i,300,40,55);
i = i + 2;
if (dummyval > 176){
k++; k = k + 2;
enem12.setBounds(k,300,40,55);
}
if (k > 176){
l++;
l = l + 2;
enem13.setBounds(l,300,40,55);
}
enem2.setBounds(u,245,40,55);
enem3.setBounds(d,190,40,55);
enem4.setBounds(n,135,40,55);
enem5.setBounds(i,410,40,55);
enem6.setBounds(u,465,40,55);
enem7.setBounds(d,520,40,55);
enem8.setBounds(n,575,40,55);
if(i > 576){ // resets button
i = 16;
}
if(k > 576){
k = 16;
}
if(u < 16){
u = 576;
}
u = u - 2; // increase lateral speed
if(d == 576) {
d = 16;
}
if(n < 16){
n = 576;
}
n = n - 5; //increases lateral speed
}
}
The problem is created because you try to manage all the "stuff" separately. It looks like you may be missing some basic information on classes
First, I would create a custom class, something like
class ButtonObject extends JButton
{
public ButtonObject(String text, int x, int y, int width, int height)
{
super(text);
this.setBounds(x, y, width, height);
}
}
You also may want to take a look at arrays and create an array of your new ButtonObject.
The for loop will help you get through all the objects in your array.
ButtonObject[] enemies = new ButtonObject[10];
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
int y = 300 - (i * 55);
enemies[i] = new ButtonObject(text, 16, y, 40, 55);
}
There is probably a better way to do it than buttons but you may want to stick with them for now for simplicity.
the basic aim is to have a JPanel filled with 9 white squares in a 3x3 pattern; The squares are 150x150 blank white .jpg files. It must be this way since later on, the program will have to change the blank squares to one of a selection of simple images, and must be able to change any square at any time.
The problem, simply, is I'm getting a NullPointerException. I have to assume it's something to do with initialising the array as null but NetBeans(yes, NetBeans...) seems to get angry with me if I don't do that. Same if I try to declare the size of the array. (That would be... "ArrayType[arraysize] arrayName;", yes?"
Egh, I'm just guessing wildly.
Edit - NullPointerException fixed, but now the blank(white) images are simply not appearing in the frame. Code below edited to reflect its new state, more potentially relevant lines added.
Here be all relevant code:
JFrame controller = new JFrame("SmartHome Interface");
controller.setVisible(true);
controller.setSize(480,500);
controller.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//[...]
JPanel labelPanel = new JPanel();
//[...]
labelPanel.setBackground(Color.GREEN);
//[...]
ImageIcon blank = new ImageIcon("../Images/blank.jpg");
//[...]
controller.add(labelPanel);
//[...]
JLabel[] labels = new JLabel[9];
for (int i = 0; i <= 8; i++)
{
int xLowBound;
int xUpBound;
int yLowBound;
int yUpBound;
//Maths for positioning the labels correctly. Should be 150px in size with 10px gaps each.
xLowBound = (i % 3) * 160;
xUpBound = xLowBound + 150;
yLowBound = (i / 3) * 160;
yUpBound = yLowBound + 150;
labels[i] = new JLabel();
labels[i].setIcon(blank);
labels[i].setBounds(xLowBound, yLowBound, xUpBound, yUpBound);
labelPanel.add(labels[i]);
}
Also.....is the filepath for the ImageIcon correct?
The code itself being located in "src/smarthome" and the images in "src/Images"
And apologies if I broke any forum conventions/codes of conduct/etc. Newby here, tried to be careful not to but I may have forgotten something.
Your problem reduces to this:
JLabel[] labels = null;
for (int i = 0; i <= 8; i++) {
labels[i].setIcon(blank);
}
This code fragment will fail because labels == null. Therefore labels[i] == null.
Use this instead:
JLabel[] labels = new JLabel[9];
for (int i = 0; i <= 8; i++) {
labels[i] = new JLabel();
labels[i].setIcon(blank);
}
Your filepath for imageIcons is incorrect. You should use:
ImageIcon img = new ImageIcon(getClass().getResource("../Images/blank.jpg"));
if your code is in static method use this:
ImageIcon img = new ImageIcon(YourClass.class.getResource("../Images/blank.jpg"));
There is a good answer about loading image icons(thanks to nIcE cOw).
You should call setVisible() and setSize() after adding all components to the frame.
Add components to frame's content pane(frame.getContentPane()).
You always should place your GUI code in separate thread.
So, your code will be:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame controller = new JFrame("SmartHome Interface");
controller.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel labelPanel = new JPanel();
labelPanel.setBackground(Color.GREEN);
// !!!
ImageIcon blank = new ImageIcon(YourClass.class
.getResource("../Images/blank.jpg"));
// !!!
controller.getContentPane().add(labelPanel);
JLabel[] labels = new JLabel[9];
for (int i = 0; i <= 8; i++)
{
int xLowBound;
int xUpBound;
int yLowBound;
int yUpBound;
xLowBound = (i % 3) * 160;
xUpBound = xLowBound + 150;
yLowBound = (i / 3) * 160;
yUpBound = yLowBound + 150;
labels[i] = new JLabel();
labels[i].setIcon(blank);
labels[i].setBounds(xLowBound, yLowBound, xUpBound,
yUpBound);
labelPanel.add(labels[i]);
}
// !!!
controller.setVisible(true);
controller.setSize(480, 500);
}
});
Mac OSX
Netbeans
JAVA
Goal: BlackJack program... Im trying to get an imageIcon of a Playing Card to display in a JLabel
Logic:
I have created some CARD objects with a method to return the imageIcon associated with it.
In my main GUI class it works if i create the new imageIcon specifying the file location -
private void newGame(){
String temp1, temp2, temp3, temp4;
card1 = hand.dealHand();
card2 = hand.dealHand();
card3 = hand.dealHand();
card4 = hand.dealHand();
image1 = new ImageIcon();
image1 = card1.getImage();
//Creates DeckImage and Logo as JLabel and adds it to userPanel
//image1 = new ImageIcon("/Users/philhunter/NetBeansProjects/PractingProgramming/src/Resources/1.png");
card1Label = new JLabel(image1, JLabel.LEFT);
userPanel.add(card1Label);
card1Label.setText("");
}
The commented out line works fine and displays the imageIcon image but when I use the card1.getImage() method then the image does not display. The method is simply -
public ImageIcon getImage(){
return this.image;
}
Also, in case you need it, here is the method that creates the CARD's from the DECK class -
private ImageIcon C1,C2, ... ,C52;
private ImageIcon[] imageArray= { C1,C2,...,C52 };
C1 = new ImageIcon("/Users/philhunter/NetBeansProjects/PractingProgramming/src/Resources/1.png");
...
C52 = new ImageIcon("/Users/philhunter/NetBeansProjects/PractingProgramming/src/Resources/52.png");
int SUITS = suit.length;
int RANKS = rank.length;
int N = SUITS * RANKS;
//Creates a deck of 52 CARD objects
theDeck = new CARD[N];
for (int i = 0; i < RANKS; i++) {
for (int j = 0; j < SUITS; j++) {
//deck[SUITS*i + j] = rank[i] + " of " + suit[j];
card = new CARD(suit[j], rank[i], value[i], imageArray[SUITS*i + j]);
theDeck[SUITS*i + j] = card;
}
}
So my question is why does the card imageIcon not display? (I am getting no error messages)
Ok, so I found the problem. I hadn't initialized the array imageArray[] with the imageIcons properly. Silly mistake but I thought I would leave this up in case other people make this silly mistake too. :)