I'm trying to create a program that lists movies in a Netflix style to learn Front-End coding.
How I want it to look in the end:
My guess is that every movie is a button component with an image a name label and a release year label.
I'm struggling to recreate this look. This is how it looks when I try it:
The navigationbar in my image is at the page start of a border layout. Below the navigationbar the movie container is in the center of the border layout.
My idea was creating a GridLayout and then create a button for each movie and adding it to the GridLayout.
You can recreate this with this code:
public class Main {
private static JFrame frame;
public static void main(String[] args) throws HeadlessException {
frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setBackground(new Color(32, 32, 32));
JPanel navigationPanel = createNavigationBar();
frame.add(navigationPanel, BorderLayout.PAGE_START);
JPanel moviePanel = createMoviePanel();
frame.add(moviePanel, BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(1920, 1080));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Example App");
frame.pack();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
public static JPanel createMoviePanel() {
JPanel moviePanel = new JPanel();
GridLayout layout = new GridLayout(0, 10);
layout.setHgap(3);
layout.setVgap(3);
moviePanel.setLayout(layout);
moviePanel.setBackground(new Color(32, 32, 32));
ArrayList<String> exampleList = new ArrayList<>();
// Add stuff to the example list
for(int i = 0; i < 120; i++) {
exampleList.add(Integer.toString(i));
}
final File root = new File("");
for(final String movie : exampleList) {
JLabel picLabel = new JLabel();
try {
File imageFile = new File(root.getAbsolutePath() + "\\src\\images\\" + "imageName.jpg"); // Try to find the cover image
if(imageFile.exists()) {
BufferedImage movieCover = ImageIO.read(imageFile);
picLabel = new JLabel(new ImageIcon(movieCover));
} else {
BufferedImage movieCover = ImageIO.read(new File(root.getAbsolutePath() + "\\src\\images\\temp.jpg")); // Get a temp image
picLabel = new JLabel(new ImageIcon(movieCover));
}
} catch (IOException e) {
e.printStackTrace();
}
JLabel movieName = new JLabel("New Movie");
movieName.setForeground(Color.WHITE);;
JButton movieButton = new JButton();
movieButton.setLayout(new GridLayout(0, 1));
//movieButton.setContentAreaFilled(false);
//movieButton.setBorderPainted(false);
//movieButton.setFocusPainted(false);
movieButton.add(picLabel);
movieButton.add(movieName);
moviePanel.add(movieButton);
}
return moviePanel;
}
public static JPanel createNavigationBar() {
JPanel navBar = new JPanel();
navBar.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 20));
navBar.setBackground(new Color(25, 25, 25));
JButton homeButton = new JButton("Home");
homeButton.setContentAreaFilled(false);
homeButton.setBorderPainted(false);
homeButton.setFocusPainted(false);
JButton movieButton = new JButton("Movies");
movieButton.setContentAreaFilled(false);
movieButton.setBorderPainted(false);
movieButton.setFocusPainted(false);
// Add all the buttons to the navbar
navBar.add(homeButton);
navBar.add(movieButton);
return navBar;
}
}
I noticed that the GridLayout always tries to fit everything onto the window.
All that's needed is a properly configured JButton in a GridLayout.
E.G.
public static JPanel createMoviePanel() {
JPanel movieLibraryPanel = new JPanel(new GridLayout(0, 10, 3, 3));
movieLibraryPanel.setBackground(new Color(132, 132, 132));
int m = 5;
BufferedImage image = new BufferedImage(9 * m, 16 * m, BufferedImage.TYPE_INT_RGB);
for (int ii = 1; ii < 21; ii++) {
JButton picButton = new JButton("Mov " + ii, new ImageIcon(image));
picButton.setMargin(new Insets(0,0,0,0));
picButton.setForeground(Color.WHITE);
picButton.setContentAreaFilled(false);
picButton.setHorizontalTextPosition(JButton.CENTER);
picButton.setVerticalTextPosition(JButton.BOTTOM);
movieLibraryPanel.add(picButton);
}
return movieLibraryPanel;
}
Here is a complete source for the above with a tweak to put the year on a new line. It uses HTML in the JButton to break the button text into two lines.
The input focus is on the first button, whereas the mouse hovers over the '2009' movie:
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
class MovieGrid {
MovieGrid() {
JFrame f = new JFrame("Movie Grid");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.add(createMoviePanel());
f.pack();
f.setVisible(true);
}
public static JPanel createMoviePanel() {
JPanel movieLibraryPanel = new JPanel(new GridLayout(0, 10, 3, 3));
movieLibraryPanel.setBackground(new Color(132, 132, 132));
int m = 5;
BufferedImage image = new BufferedImage(
9 * m, 16 * m, BufferedImage.TYPE_INT_RGB);
for (int ii = 2001; ii < 2021; ii++) {
JButton picButton = new JButton(
"<html>Movie<br>" + ii, new ImageIcon(image));
picButton.setMargin(new Insets(0,0,0,0));
picButton.setForeground(Color.WHITE);
picButton.setContentAreaFilled(false);
picButton.setHorizontalTextPosition(JButton.CENTER);
picButton.setVerticalTextPosition(JButton.BOTTOM);
movieLibraryPanel.add(picButton);
}
return movieLibraryPanel;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new MovieGrid();
}
};
SwingUtilities.invokeLater(r);
}
}
Same idea's from Andrew Thompson answer but with some minor text alignment changes and hover effect
final class Testing
{
public static void main(String[] args)
{
JFrame frame=new JFrame("NEFLIX");
frame.setContentPane(new GridDisplay());
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static final class GridDisplay extends JPanel implements ActionListener
{
private GridDisplay()
{
super(new GridLayout(0,5,20,20));
setBackground(new Color(0,0,0,255));
BufferedImage image=new BufferedImage(150,200,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d=(Graphics2D)image.getGraphics();
g2d.setColor(Color.BLUE);
g2d.fillRect(0,0,image.getWidth(),image.getHeight());
HoverPainter painter=new HoverPainter();
for(int i=0;i<10;i++)
{
TVShowCard card=new TVShowCard(image,"Show "+i,"199"+i);
card.addMouseListener(painter);
add(card);
}
}
//highlight only on hover
private final class HoverPainter extends MouseAdapter
{
#Override
public void mouseExited(MouseEvent e) {
((TVShowCard)e.getSource()).setBorderPainted(false);
}
#Override
public void mouseEntered(MouseEvent e) {
((TVShowCard)e.getSource()).setBorderPainted(true);
}
}
private final class TVShowCard extends JButton
{
private TVShowCard(BufferedImage preview,String name,String year)
{
super();
setContentAreaFilled(false);
setBackground(new Color(0,0,0,0));
setFocusPainted(false);
setBorderPainted(false);
//I didn't use image icon & text horizontal alignment because the text always horizontally centered aligned but from the expected output it was left so created 2 labels for the job
setLayout(new GridBagLayout());
addIcon(preview);
addLabel(name,year);
addActionListener(GridDisplay.this);
}
private void addIcon(BufferedImage preview)
{
JLabel icon=new JLabel();
icon.setIcon(new ImageIcon(preview));
add(icon,new GridBagConstraints(0,0,1,1,1.0f,0.0f,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(0,0,0,0),0,0));
}
private void addLabel(String name,String year)
{
JLabel label=new JLabel("<html><body>"+name+"<br>"+year+"</body></html>");
label.setForeground(Color.white);
label.setBackground(new Color(0,0,0,0));
add(label,new GridBagConstraints(0,1,1,1,1.0f,1.0f,GridBagConstraints.SOUTHWEST,GridBagConstraints.NONE,new Insets(5,0,0,0),0,0));
}
}
#Override
public void actionPerformed(ActionEvent e)
{
TVShowCard card=(TVShowCard)e.getSource();
//do stuff with it
}
}
}
I am trying to create a board class that extends JPanel for a backgammon game and a JLayeredPane to create a dragging area for my checkers but i cant even print a simple rectangle to the panel. It does print the image but not the JLabel.
Here is my JPanel class
public class BoardPanel extends JPanel{
private JLayeredPane lp;
private BufferedImage imageBoard;
private final int WIDTH = 1000;
private final int HEIGHT = 800;
private ArrayList<Slot> slotSet1;
private ArrayList<Slot> slotSet2;
private ArrayList<Slot> slotSet3;
private ArrayList<Slot> slotSet4;
private CheckerSet ch1;
public Checker chc;
public BoardPanel(){
initComponents();
}
private void initComponents(){
lp = new JLayeredPane();
setPreferredSize(new java.awt.Dimension(1500, 1000));
//lp.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
lp.setBorder(javax.swing.BorderFactory.createTitledBorder("asdadsaddadsadasdadsa"));
lp.setMaximumSize(new java.awt.Dimension(1124, 904));
lp.setMinimumSize(new java.awt.Dimension(1124, 904));
try {
imageBoard = ImageIO.read(getClass().getResource("/images/board.jpg"));
} catch (IOException e) {
System.out.println("file error");
}
JLabel label = new JLabel();
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setOpaque(true);
label.setBackground(Color.BLACK);
label.setForeground(Color.black);
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.setBounds(0, 0, 50, 50);
lp.add(label,JLayeredPane.DEFAULT_LAYER);
}
public void paintComponent(Graphics g){
//g.drawImage(imageBoard,0,0,null);
}
}
And there is the main
public static void main(String[] args){
JFrame f = new JFrame();
//GamePanel gp = new GamePanel();
BoardPanel gp = new BoardPanel();
f.add(gp);
//f.getContentPane().add(gamePanel);
f.setSize(new Dimension(1500, 1000));
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
How can i resolve it? Thanks guys
You will have to add a Layout to your JLayeredPane, like a GridLayout for example. Try this:
GridLayout gl = new GridLayout(20, 21);
lp.setLayout(gl);
after initializing lp. Then you can add all components that you Need to the GridLayout, for instance lp:
gl.add(lp)
The Layout will manage how the things will be displayed; in this case, it will fill the grid from the GridLayout, first the first row (of which 20 exist), then the second one and so on (I don't think you actually Need 20 rows, it is just like that in my example code)
So I'm trying to animate(draw different png image file continuously) on JPanel but if I run this JPanel, there is only white screen.
And I'm trying to draw BufferedImage on the JPanel
public void run() {
try {
while (true) {
if (GAME_STATE) {
..................
}
getContentPane().repaint();
getContentPane().revalidate();
Thread.sleep(GAME_SPEED);
}
} catch (Exception e) {
}
}
This is run method which calls repaint() and revalidate()
public class Panel_Game extends JPanel {
private static final long serialVersionUID = 1L;
Panel_Game() {
// set a preferred size for the custom panel.
this.setPreferredSize(new Dimension(f_width, f_height + 100));
this.setVisible(true);
this.setLayout(null);
this.setDoubleBuffered(true);
this.setFocusable(true);
this.requestFocus(true);
}
#Override
public void paint(Graphics g) {
buffImage = createImage(f_width, f_height + 100);
buffg = buffImage.getGraphics();
getContentPane().revalidate();
super.paintComponent(g);
Draw_Background();
Draw_Player();
Draw_Weapon();
Draw_Enemy();
Draw_EnemyWeapon();
Draw_Item();
.............
g.drawImage(buffImage, 0, 0, this);
}
}
And this is a class that I try to draw image on
public void Game_InterFace() {
JLabel Label_Menu_Board = new JLabel();
JLabel Label_AP_Board = new JLabel();
JLabel Label_Save_Board = new JLabel();
JLabel Label_Load_Board = new JLabel();
Panel_Game panel_Game = new Panel_Game();
panel_Game.addKeyListener(this);
.............................................
.............................................
panel_Game.add(btn_Menu);
panel_Game.add(btn_AP);
panel_Game.add(label_Status);
getContentPane().add(panel_Game);
getContentPane().repaint();
}
.......
public Game_main() {
start();
setLocation(0, 0);
setUndecorated(true);
setSize(f_width, f_height);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.setLayout(null);
Game_Home();
}
I have a desktop application in swing. I have a JPanel in which the image as the background and in it two buttons and a JScrollPane as shown in the picture Frame with JPanel. I have a function (showLabel()) which, when JScrollPane the end, add JLabel with transparent images and disappear a few seconds. The problem is that when you add JLabel. JLabel bad shows as seen in Fig Bad shows. Can you help me with my problem?
public class MainWindow {
private JFrame frame;
private PanelPopis panelPopis = new PanelPopis(this);
private MyPaint myPaint;
public MainWindow {
setWindow():
BufferedImage image1 = ImageIO.read(getClass().getClassLoader().getResource("poz.png"));
this.myPaint = new MyPaint(image1);
this.frame.add(myPaint);
this.myPaint.add(panelPopis.setPanel());
}
private void setWindow() {
this.frame = new JFrame("DD");
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.frame.setSize(400, 680);
this.frame.setResizable(false);
this.frame.setLocationRelativeTo(null);
}
private void showLabel(){
JLabel label = new JLabel();
label.setIcon(new ImageIcon(new ImageIcon(getClass().getClassLoader().getResource("postEn.png")).getImage().getScaledInstance(395, 653, Image.SCALE_DEFAULT)));
label.setBackground(new Color(0, 0, 0, 10));
label.setOpaque(true);
this.frame.invalidate();
this.frame.add(label);
this.frame.revalidate();
int delay2 = 3000; // milliseconds
ActionListener taskPerformer2 = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
frame.remove(label);
frame.revalidate();
frame.repaint();
}
};
Timer myTimer2 = new Timer(delay2, taskPerformer2);
myTimer2.setRepeats(false);
myTimer2.start();
}
}
public class MyPaint extends JPanel {
private static final long serialVersionUID = 1L;
BufferedImage image;
public MyPaint(BufferedImage image) {
setOpaque(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 395, 653, this);
}
}
public class PanelPopis extends JPanel {
private static final long serialVersionUID = 7676683627217636485L;
private JButton setLanguage;
private JButton cont;
private JScrollPane scrolPanel;
private JTextArea popis;
private MainWindow mainWindow;
public PanelPopis(MainWindow mainWindow) {
this.mainWindow = mainWindow;
}
public JPanel setPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setOpaque(false);
JPanel panel2 = new JPanel();
Border border = panel2.getBorder();
Border margin = new EmptyBorder(0, 0, 4, 0);
panel2.setBorder(new CompoundBorder(border, margin));
panel2.setOpaque(false);
panel2.add(this.scrolPanel = new JScrollPane(popis));
panel.add(this.setLanguage = new JButton("language settings"), BorderLayout.NORTH);
panel.add(this.cont = new JButton("CONTINUE"), BorderLayout.SOUTH);
panel.add(panel2, BorderLayout.CENTER);
return panel;
}
}
I would suggest to use the getResource() method instead of the getResourceAsStream() and have the path of both images inputted there this way.
The classLoader could behave differently (in your case due to the differences between the two OS's) so doing it this way would guarantee that you application is always getting the correct resources.
More on the getResource here:
https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
I'm writing a Java program and I use JSplitPane to split between two JTextPanes.
The bottom JtextPane is in JTabbedPane.
public class test extends JFrame{
private JTextPane commandTextPane = new JTextPane();
private JPanel tokenPanel;
private JTextPane tokenTextPane = new JTextPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
test window = new test();
window.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public test (){
setBounds(100, 100, 900, 700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
commandTextPane.setBounds(0, 0, 200, 300);
commandTextPane.setPreferredSize(new Dimension(200, 300));
//create ressultTabPane
JTabbedPane resultTabPane = new JTabbedPane();
tokenTabPanel();
resultTabPane.addTab("Token", tokenPanel);
JScrollPane topScroll = new JScrollPane(commandTextPane,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
TextLineNumber topLine = new TextLineNumber(commandTextPane);
topScroll.setRowHeaderView(topLine);
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
topScroll, resultTabPane);
splitPane.setOneTouchExpandable(true);
getContentPane().add(splitPane);
setVisible(true);
}
public void tokenTabPanel() {
tokenPanel = new JPanel();
tokenTextPane.setBounds(0, 0, 200, 300);
tokenTextPane.setPreferredSize(new Dimension(200,300));
JScrollPane tokenScroll = new JScrollPane(tokenTextPane,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
TextLineNumber tokenLine = new TextLineNumber(tokenTextPane);
tokenScroll.setRowHeaderView(tokenLine);
tokenPanel.add(tokenScroll);
}
}
The problem is I can't set Bounds and PreferedSize of those JTextPanes. When I set them, the top JTextPane is not expect size and the bottom JTextPane is not in the top-left also its size.
image --> (http://upic.me/show/54858871)
Do you know how to fix them? Sorry for my English.
Thanks in advance.