问题
When I added JComboBox, JRadioButton, JButton to JPanel, it was working fine, but after I added them to JFrame instead and executed it, all these components were gone. My code is listed below:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test21 {
public static void main(String[] args) {
JFrame jf = new JFrame("康樂彩歌(v0)");
jf.setBounds(0, 0, 1368, 730);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label1 = new JLabel("選歌:"); //創建標簽
label1.setFont(new Font("新細明體", Font.PLAIN, 20));
jf.add(label1);
JComboBox cmbox = new JComboBox(); //創建JComboBox
//cmb.setLocation(500,500);
cmbox.setFont(new Font("新細明體", Font.PLAIN, 30));
//cmb.setBounds(120,80,150,30);
cmbox.addItem("紫竹調");
cmbox.addItem("走一同去郊遊");
cmbox.addItem("大野狼");
cmbox.addItem("歸來吧蘇連多");
cmbox.addItem("追尋");
cmbox.addItem("三輪車");
cmbox.addItem("我家門前有小河");
cmbox.addItem("漁家樂");
cmbox.addItem("嚕啦啦");
cmbox.addItem("踏雪尋梅");
jf.add(cmbox);
JRadioButton rb2 = new JRadioButton("加人聲", false);
rb2.setFont(new Font("新細明體", Font.PLAIN, 20));
jf.add(rb2);
JButton btPlay = new JButton("PLAY");
btPlay.setFont(new Font(Font.DIALOG_INPUT, Font.BOLD, 25));
jf.add(btPlay);
//JButton btStop = new JButton("STOP");
//btStop.setFont(new Font(Font.DIALOG_INPUT, Font.BOLD, 25));
Panel1 jp1 = new Panel1();//Panel1() is a class included in the same project
jp1.setBorder(BorderFactory.createLineBorder(Color.black));
jf.add(jp1);
jp1.move = false;
jp1.display();
jf.setVisible(true);
btPlay.addActionListener(new ActionListener() {//加上事件接收器-對按钮PLAY
@Override
public void actionPerformed(ActionEvent e) {//接收到事件後進行以下的處理
Thread a = new Thread()
{
public void run()
{
AudioTest1 runAudio = new AudioTest1();//AudioTest1 is a class included in
the same project.
runAudio.audioFileName = "audio1.wav";
runAudio.AudioPlay();
}
};
Thread b = new Thread()
{
public void run()
{
jp1.move = true;
jp1.display();
}
};
a.start();
b.start();
}
});
}
}
Initially, I added these components to JPanel as jp1.add(cmbox), jp1.add(rb2), jp1.add(btPlay) instead of jf.add(cmbox), jf.add(rb2), jf.add(btPlay) it was working fine. Panel1.java is listed below:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JPanel;
class Panel1 extends JPanel{
int x[] = new int[59]; //the x position of each note
int y[] = new int[59]; //the y position of each note
int width[] = new int[59]; //the width of each note
int height = 20; //the height of each note
Color color[] = new Color[59];//the color of each note
Boolean move;
JButton btStop = new JButton("STOP");
//btStop.setFont(new Font(Font.DIALOG_INPUT, Font.BOLD, 25));
String[] lyric = {"一", " 根", "紫~", "竹", "直~", "苗~", "苗,", "送", "給", "寶", "寶", "做", "管", "簫,",
"簫", "兒", "對", "準", "口,", "口", "兒", "對", "準", "簫,",
"簫~", "中", "吹~", "出", "新~", "時~ ", "調,",
"小", "寶~", "寶,", "小", "寶~", "寶,",
"咿", "底", "咿", "底", "學 ", "會", "了,", "啊 ~ ~ ~"};//共45個
int[] numNotes = {1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 1, 2, 1, 2, 2, 1,
1, 2, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 1, 6};//共45個
int[][] notes = {{5,2},{8,2},{6,1},{5,1},{3,2},{5,1},{2,1},{3,1},{2,1},{1,4},{6,1},{8,1},
{3,1},{5,1},{6,2},{3,2},{5,8},{8,1},{6,1},{3,1},{6,1},{5,4},{6,1},{8,1},
{3,1},{6,1},{5,4},{5,1},{6,1},{8,2},{6,1},{5,1},{3,2},{5,1},{2,1},{3,1},
{2,1},{1,4},{1,2},{1,1},{3,1},{2,4},{1,2},{1,1},{3,1},{2,4},{6,1},{8,1},
{6,1},{8,1},{9,2},{6,2},{5,3},{6,1},{2,1},{3,1},{5,1},{6,1},{5,8}};//共59個
String[] simplifiedNote = {"| 5", " 1", " 6", "5", "3", "| 5", "2", "3", "2", "1 - ", "| 6", "1",
"3", "5", "6", " 3", "| 5 - - -", "| 1", "6", "3", "6", "5 - ", "| 6", "5",
"3", "6", "5 -", "| 5", "6", "1", "6", "5", " 3", "| 5", "2", "3",
"2", "1 -", "| 1", "1", "3", "2 -", "| 1", "1", "3", "2 -", "| 6", "1",
"6", "1", "2", "6", "| 5 .", "6", "2", "3", "5", "6", "| 5 - - - "};//共59個
Color color0 = new Color(255,255,255); //白色
Color color1 = new Color(255,0,0); //紅色
Color color2 = new Color(255,165,0); //橙色
Color color3 = new Color(255,255,0); //黃色
Color color4 = new Color(0,128,0); //綠色
Color color5 = new Color(0,0,255); //藍色
Color color6 = new Color(75,0,130); //靛色
Color color7 = new Color(100,0,153); //紫色
Color color8 = new Color(153,0,0); //暗紅
Color color9 = new Color(0,0,0); //黑色
Color color10 = new Color(37,255,255); //淺藍
public void display(){
for (int i = 0;i < notes.length; i++) {
//System.out.println("notes[" + i + "][0] = " + notes[i][0]);
switch (notes[i][0]) {
case 1:
y[i] = 400;
color[i] = color1;
break;
case 2:
y[i] = 400 - 20;
color[i] = color2;
break;
case 3:
y[i] = 400 - 20*2;
color[i] = color3;
break;
case 4:
y[i] = 400 - 20*3;
color[i] = color4;
break;
case 5:
y[i] = 400 - 20*4;
color[i] = color5;
break;
case 6:
y[i] = 400 - 20*5;
color[i] = color6;
break;
case 7:
y[i] = 400 - 20*6;
color[i] = color7;
break;
case 8:
y[i] = 400 - 20*7;
color[i] = color1;
break;
case 9:
y[i] = 400 - 20*8;
color[i] = color2;
}
switch (notes[i][1]) {
case 1: width[i] = 20;
break;
case 2: width[i] = 20 * 2;
break;
case 3: width[i] = 20 * 3;
break;
case 4: width[i] = 20 * 4;
break;
case 5: width[i] = 20 * 5;
break;
case 6: width[i] = 20 * 6;
break;
case 7: width[i] = 20 * 7;
break;
case 8: width[i] = 20 * 8;
}
}
x[0] = 100;
for (int i = 1; i < notes.length; i++){
x[i] = x[i-1] + width[i-1];
}
int timeLast = 0; //total executing time
if (move == true) {
while(timeLast < 900){
for (int i = 0; i < notes.length; i ++){
x[i]--;
}
this.repaint();
try {Thread.sleep(50);}
catch (InterruptedException e){
e.printStackTrace();
}
timeLast = timeLast + 1;
}
}
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(color9);
g2d.setFont(new Font("新細明體", Font.BOLD, 20));
int y1 = 130; //C調 4/4 Y坐標
int y2 = 180; //簡譜行Y坐標
int y3 = 210; //歌詞行Y坐標
int y4 = 163; //加高音點
int y5 = 180; //加八分音符底線
int y6 = 470; //色彩音符說明
int chrPosition = 0;
g2d.drawString("C調 4/4", 16, y1);
//色彩音符說明
g2d.drawString("色彩音符:", 16, y6);
g2d.setColor(color1);
g2d.fillRoundRect(126, y6-16, 20,20, 3,3);
g2d.setColor(color9);
g2d.drawString(": Do", 150, y6);//126 + 24
g2d.setColor(color2);
g2d.fillRoundRect(206, y6-16, 20,20, 3,3);//150 + 56
g2d.setColor(color9);
g2d.drawString(": Re", 230, y6);//206 + 24
g2d.setColor(color3);
g2d.fillRoundRect(286, y6-16, 20,20, 3,3);//230 + 56
g2d.setColor(color9);
g2d.drawString(": Mi", 310, y6);//286 + 24
g2d.setColor(color4);
g2d.fillRoundRect(366, y6-16, 20,20, 3,3);//310 + 56
g2d.setColor(color9);
g2d.drawString(": Fa",390, y6);//366 + 24
g2d.setColor(color5);
g2d.fillRoundRect(446, y6-16, 20,20, 3,3);//390 + 56
g2d.setColor(color9);
g2d.drawString(": So", 470, y6);//446 + 24
g2d.setColor(color6);
g2d.fillRoundRect(526, y6-16, 20,20, 3,3);//470 + 56
g2d.setColor(color9);
g2d.drawString(": La", 550, y6);//526 + 24
//g2d.setColor(color7);
//g2d.fillRoundRect(606, y6-16, 20,20, 3,3);//550 + 56
//g2d.setColor(color9);
//g2d.drawString(":Si", 630, y6);//606 + 24
//寫出簡譜
for (int i = 0;i < simplifiedNote.length; i++){
g2d.drawString(simplifiedNote[i], x[i], y2);
}
//在簡譜下方寫出歌詞
g2d.setColor(color9);
for (int i = 0; i < lyric.length; i++){
if (i != 0 && numNotes[i-1] == 2) {
chrPosition = chrPosition + 1;
g2d.drawString(lyric[i], x[chrPosition], y3);
}
else {
g2d.drawString(lyric[i], x[chrPosition], y3);
}
chrPosition = chrPosition + 1;
}
//在簡譜上方加高音點
g2d.setColor(color9);
g2d.drawString(".", x[1]+14, y4);
g2d.drawString(".", x[11]+2, y4);
g2d.drawString(".", x[17]+11, y4);
//g2d.drawString(".", x[23]+2, y4);
g2d.drawString(".", x[29]+2, y4);
g2d.drawString(".", x[47]+2, y4);
g2d.drawString(".", x[49]+2, y4);
g2d.drawString(".", x[50]+2, y4);
//在簡譜下方加八分音符底線
g2d.setColor(color9);
g2d.drawString("_", x[2]+4, y5);
g2d.drawString("_", x[3], y5);
g2d.drawString("_", x[5]+8, y5);
g2d.drawString("_", x[6], y5);
g2d.drawString("_", x[7], y5);//5
g2d.drawString("_", x[8], y5);
g2d.drawString("_", x[10]+8, y5);
g2d.drawString("_", x[11], y5);
g2d.drawString("_", x[12], y5);
g2d.drawString("_", x[13], y5);//10
g2d.drawString("_", x[17]+8, y5);
g2d.drawString("_", x[18], y5);
g2d.drawString("_", x[19], y5);
g2d.drawString("_", x[20], y5);
g2d.drawString("_", x[22]+8, y5);//15
g2d.drawString("_", x[23], y5);
g2d.drawString("_", x[24], y5);
g2d.drawString("_", x[25], y5);
g2d.drawString("_", x[27]+8, y5);
g2d.drawString("_", x[28], y5);//20
g2d.drawString("_", x[30], y5);
g2d.drawString("_", x[31], y5);
g2d.drawString("_", x[33]+8, y5);
g2d.drawString("_", x[34], y5);
g2d.drawString("_", x[35], y5);
g2d.drawString("_", x[36], y5);//25
g2d.drawString("_", x[39], y5);
g2d.drawString("_", x[40], y5);
g2d.drawString("_", x[43], y5);//1
g2d.drawString("_", x[44], y5);//3
g2d.drawString("_", x[46]+8, y5);//6
g2d.drawString("_", x[47], y5);//1
g2d.drawString("_", x[48], y5);//6
g2d.drawString("_", x[49], y5);//1
g2d.drawString("_", x[53], y5);//6
g2d.drawString("_", x[54], y5);//2
g2d.drawString("_", x[55], y5);//3
g2d.drawString("_", x[56], y5);//5
g2d.drawString("_", x[57], y5);//6
//在歌詞下方繪出彩色譜
for (int i = 0;i < notes.length; i++){
g2d.setColor(color[i]);
g2d.fillRoundRect(x[i], y[i], width[i], height, 3,3); //畫圓角方塊
g2d.setColor(color8);
g2d.drawLine(x[i],230, x[i]+width[i], 230);//畫水平上線
g2d.setColor(color8);
g2d.drawLine(x[i],231, x[i], 429);//畫直紅線
g2d.setColor(color8);
g2d.drawLine(x[i],430, x[i]+width[i], 430);//畫水平下線
}
g2d.setColor(color8);
g2d.drawLine(x[notes.length-1]+ width[notes.length - 1],231, x[notes.length - 1] + width[notes.length - 1],429);//畫邊界直紅線
}
}
AudioTest1.java is listed below:
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
class AudioTest1 {//to play the music
String audioFileName;
public void AudioPlay() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try{
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(classLoader.getResourceAsStream(audioFileName));
clip.open(inputStream);
clip.start();
while (!clip.isRunning())
Thread.sleep(0);
while (clip.isRunning())
Thread.sleep(0);
clip.close();
} catch (Exception e)
{
e.printStackTrace();
System.out.println(e);
}
}
}
My goal is to list all songs in JComboBox to let user chose a song and see what the score is. When the PLAY button is clicked, the score starts to move, simultaneously the music is played.
回答1:
This is because by default a JPanel
uses a FlowLayout that shows added Components one after the other
JFrame
uses a BorderLayout where at most five components can be placed (one in each of the regions PAGE_START, PAGE_END, LINE_START, LINE_END, CENTER). If you don't specify the region the component is placed into the CENTER region. If you try to place more than one component into one region one the last one will show up.
For your problem I would recommend to create a JPanel
that contains your JLabel
, JComboBox
, JRadioButton
and the JButton
and add the JPanel
to the JFrame
like this:
JPanel buttonPanel = new JPanel();
buttonPanel.add(label1); // instead of jf.add(label1);
buttonPanel.add(cmbox); // instead of jf.add(cmbox);
buttonPanel.add(rb2); // instead of jf.add(rb2);
buttonPanel.add(btPlay); // instead of jf.add(btPlay);
jf.add(buttonPanel, BorderLayout.PAGE_START);
Why your components don't show up if you do
jf.setLayout(null);
jp1.setBounds(0, 100, 1368, 730);
That is simple: if you want to use absolute positioning by writing jf.setLayout(null);
you have to define the bounds of every component yourself.
And that doesn't scale well: it is a tedious task and if people have different font size settings you are almost guaranteed to make somebody unhappy.
It is much better to learn how the various layout managers work and use these appropriately. To learn about the layout managers you find important documentation at https://docs.oracle.com/javase/tutorial/uiswing/layout/index.html
回答2:
Thanks to Thomas' help! I have corrected my code and it's working fine now as following:
JFrame jf = new JFrame("康樂彩歌(v0)");
jf.setBounds(0, 0, 1368, 730);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(null);
JComboBox cmbox = new JComboBox();
cmbox.setBounds(150, 5, 150, 40);
cmbox.setLocation(450,0);
cmbox.setFont(new Font("新細明體", Font.PLAIN, 30));
cmbox.addItem("紫竹調");
cmbox.addItem("走一同去郊遊");
cmbox.addItem("大野狼");
cmbox.addItem("歸來吧蘇連多");
cmbox.addItem("追尋");
cmbox.addItem("三輪車");
cmbox.addItem("我家門前有小河");
cmbox.addItem("漁家樂");
cmbox.addItem("嚕啦啦");
cmbox.addItem("踏雪尋梅");
//cmbox.addActionListener(this);
jf.add(cmbox);
JRadioButton rb2 = new JRadioButton("加人聲", false);
rb2.setFont(new Font("新細明體", Font.PLAIN, 20));
rb2.setBounds(605, 8, 90, 30);
jf.add(rb2);
JButton btPlay = new JButton("PLAY");
btPlay.setFont(new Font(Font.DIALOG_INPUT, Font.BOLD, 25));
btPlay.setBounds(700, 0, 100, 40);
jf.add(btPlay);
Panel1 jp1 = new Panel1();
jp1.setBounds(0, 70, 1368, 630);
jf.add(jp1);
来源:https://stackoverflow.com/questions/60861243/why-after-i-added-components-to-jframe-instead-of-adding-them-to-jpanel-all-thes