Can anyone tell me why my volume control doesn't work...?
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.sound.sampled.*;
import javax.swing.event.*;
/*<Applet code="kkk" height=400 width=400></Applet>*/
public class kkk extends JComponent
{
static File f1;
int prog;
static JFrame jf;
int al;
JLabel time;
Timer tr;
Button b;
int pos=0;
Clip c;
AudioInputStream a;
JSlider s;
public static void main(String args[])
{
f1=new File("mm.wav");
jf=new JFrame();
jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
kkk kp=new kkk(f1);
jf.getContentPane().add(kp, "Center");
jf.setSize(400,400);
jf.setVisible(true);
}
kkk(File f1)
{
try
{
a=AudioSystem.getAudioInputStream(f1);
AudioFormat af=a.getFormat();
DataLine.Info di=new DataLine.Info(Clip.class,af);
c=(Clip)AudioSystem.getLine(di);
c.open(a);
}
catch(Exception e)
{
System.out.println("Exception caught ");
}
finally
{
try
{
a.close();
}
catch(Exception e)
{
System.out.println("Exception caught ");
}
}
al=(int)(c.getMicrosecondLength()/1000);
s=new JSlider();
Button b=new Button("play");
time=new JLabel();
Box row = Box.createHorizontalBox();
row.add(s);
row.add(b);
row.add(time);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent eee)
{
play();
}});
s.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent ee)
{
//repaint();
prog=s.getValue();
time.setText(prog / 1000 + "." + (prog % 1000) / 100);
//if(prog!=ap)
//skip(prog);
}});
tr = new javax.swing.Timer(100, new ActionListener() {
public void actionPerformed(ActionEvent e) {
tick();
}
});
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.add(row);
}
public void play()
{
try
{
FloatControl volume = (FloatControl) c.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(-20.63f);
}
catch(Exception e)
{}
c.start();
tr.start();
}
//public void skip(
public void tick()
{
pos = (int) (c.getMicrosecondPosition() / 1000);
s.setValue(pos);
}
}
The volume never changes just because...you're never changing it !
I suppose you want the volume to be modified when the slider state changes, so you just have to set the volume in your stateChanged method. In order to do this, you can use the following instruction: volume.setValue(-20.63f) that you have already used elsewhere in your program. Just replace the parameter by the value you want (e.g. the value of the slider).
Hope this helps.
OK, it seems like you made the "volume" control correctly. Are you saying you put different values in the following line and it always sounded the same volume?
volume.setValue(-20.63f);
I can't imagine what values of 10 or 80 would do, as I think the range is -80 to 6. And most of the bottom end of that is pretty much inaudible. It's supposed to correspond to decibels from -80 to 6 or volts or something more typical to a VU meter. My mixer has a VU meter that ranges from -20 to +5, for example.
In any event, trying test values like 5 or 0 or -10 might have a better chance of sounding like something.
Also, most people expect that one changes the volume during playback, as a dynamic process, and so we are looking for logical places in your code to do this, such as the Timer or the Slider. But I guess you were just trying to get sounds to play at different hard-coded sound levels, and the slider was just for displaying progress. I found the code rather hard to decipher, as well as the description of the problem.
Related
I am trying to make a simple program that will ask the user a question and then compare their answer with a stored correct answer. The problem seems to be that the main loop of the program is not running when I click the Ready JButton.
I tried changing the main method to another non-default name and adding a call to it in the actionPerformed() method, and it did seem to execute the loop at least once, but then led to not being able to close the applet without the task manager once I clicked the button. I don't know if that means it hit an endless loop or what.
I'm sure there is more to fix in this code besides this issue, but I cannot make any progress on that without clearing this up first. If there is a problem with the way I went about creating the GUI please let me know. I tried to base it off of an assignment I did that worked just fine, so I don't know whether or not that is the issue.
Any help provided is appreciated.
Here is the code:
import java.awt.*;
import javax.swing.*;
public class Langarden_App extends JApplet{
private int width = 800, height = 600;
private LangardenPanel langPanel;
public void init(){
langPanel = new LangardenPanel();
getContentPane().add(langPanel);
setSize(width, height);
}
}
And the class with the logic
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.*;
public class LangardenPanel extends JPanel{
private static JButton submit;
private static JButton ready = new JButton("Ready");
private static JLabel instruct;
private JTextField input = new JTextField(100);
private static String inString;
private static ArrayList<String> questions;
private static ArrayList<String> answers;
private static Random rand = new Random();
public LangardenPanel(){
questions = new ArrayList<String> (Arrays.asList("¿Qué es la palabra para 'inveirno' en ingles?", "¿Qué es la forma de 'yo' del verbo 'venir'?"));
answers = new ArrayList<String> (Arrays.asList("winter", "voy"));
instruct = new JLabel("Welcome to Langarden! Press Submit to begin. You have one minute and three attempts for each question.");
submit = new JButton("Submit");
this.setLayout(new BorderLayout());
add(BorderLayout.SOUTH, ready);
add(BorderLayout.NORTH, instruct);
add(BorderLayout.CENTER, input);
ready.addActionListener(new SubListener());
}
public static void main(String[] args){
try{
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e){
}
System.out.println("Setting text");
instruct.setText("Alright! Let's Go!");
try{
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e){
}
do{
System.out.println("Running loop");
int qnum = rand.nextInt(questions.size());
instruct.setText(questions.get(qnum));
for (int i=0; i<3; i++){
try {
TimeUnit.SECONDS.sleep(60);
} catch (InterruptedException e) {
}
if(checkAnswer(qnum, inString)){
instruct.setText("Correct!");
break;
} else {
instruct.setText("Try again...\n" + questions.get(qnum));
}
}
instruct.setText("The correct answer was " + answers.get(qnum));
try{
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e){
}
questions.remove(qnum);
answers.remove(qnum);
instruct.setText("Would you like to continue? Enter No and click Submit to exit.");
} while (!inString.equalsIgnoreCase("No") && questions.size() != 0);
instruct.setText("Congratulations, you have completed this module!");
}
private static boolean checkAnswer(int qnum, String inString) {
if (answers.get(qnum).equalsIgnoreCase(inString))
return true;
return false;
}
private class SubListener implements ActionListener{
public void actionPerformed(ActionEvent e){
System.out.println("Button Pressed!");
if(e.getSource() == ready){
add(BorderLayout.SOUTH, submit);
submit.addActionListener(new SubListener());
} else {
inString = input.getText();
}
}
}
}
Get rid of the main method. If this is running as an applet, then the program has no business having a main method.
Make all fields non-static. Yes all.
Get rid of the while-true loop. If this runs, this will squelch your Swing event thread rendering your GUI frozen and helpless. Use a Swing Timer instead as a "pseudo" loop. Please check out the Swing Timer Tutorial for more on this.
Any time you add a component to a container, you should call revalidate() and repaint() on that same container so that the container's layout managers can layout the new component, and so that the OS can repaint over any "dirty" pixels.
Rather than add a new JButton as you're doing, much better is to swap components using a CardLayout. The tutorial can be found here: CardLayout tutorial.
First of all, it's not really a virus that is used to spy, or steal bank accounts. I don't even know if it's a virus at all. I only made it to troll friends/people I know, and practice my programming skills. I will show you the code, then I will try to explain it a bit;
package pracatice;
import java.awt.event.*;
import javax.swing.*;
public class practice extends JFrame
{
public static boolean bool = true;
public static int x = 0;
public static int y = 0;
public static int num = 0;
public static TimerClass tc = new TimerClass();
public static Timer timer = new Timer(30, tc);
public JPanel panel = new JPanel();
public JButton btn = new JButton("press");
public practice()
{
setSize(100,100);
setTitle("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPanel();
setVisible(true);
}
public void setPanel()
{
btn.addActionListener(new listener());
panel.add(btn);
add(panel);
}
public class listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
num = 0;
timer.start();
}
}
public static class TimerClass implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
do
{
num++;
JOptionPane optionPane = new JOptionPane("PC afected by virus");
JDialog dialog = optionPane.createDialog(null, "Virus");
dialog.setModal(false);
dialog.setLocation(x, y);
dialog.show();
updateCordinates();
}while(bool == true);
}
}
public static void updateCordinates()
{
if(x != 1100)
x += 100;
else if(x == 1100)
{
x = 0;
y += 50;
}
if(y == 650)
y =0;
}
public static void main(String[] args)
{
new practice();
}
}
So, at first it obviously builds a window, 100 X 100 px big. It adds a button that says "press". When you press, it starts a new loop, every 30 milliseconds.
every iteration of the loop, it puts in a new JOPtionPane.showMessageBox(null,...) in a slightly different location.
At first, when I just made it, I didn't know it would be unstoppable. I ran it, and had to restart my laptop. When I pressed ok, it would put in another box, in the exact same spot. When I tried to open task manager, it would automatically minimize it, and go back into the "virus" window. So, the laptop was unusable. I had to restart it, closing some of my dads tabs...
Here are a few things I would like to find out;
1) If I left this run over night, is it possible, that the laptop ran out or RAM, and if it did, what would happen?
2) Can I make it that, when I press a button on the keyboard, the whole thing just closes?
Like I said before, I was only trying to prank my friends, and the program happened to not be closable... any advice?
Yes, the computer will eventually run out of RAM. When that happens, nothing disastrous should happen other than your program crashing.
Not very easily, because JOptionPane windows don't let keyboard events get to the rest of the program. You'd need to use your own type of window instead of JOptionPane. You could then use a KeyListener that does System.exit(0).
In my online Java class, I need to write a program that counts the number of mouse clicks on a button within a frame. Here is my code:
import java.awt.*;
import java.awt.event.*;
public class option1 extends Frame {
option1() {
setTitle("Final Project Option 1");
setSize(300,300);
show();
}
public static void main(String[] args) {
option1 test = new option1();
int a = 0;
String s1 = "" + a;
Frame objFrame;
Button objButton1;
Label objLabel1;
objFrame = new option1();
objButton1 = new Button("Button");
objLabel1 = new Label();
objLabel1.setBounds(150,220,50,30);
objButton1.setBounds(40,35,50,50);
objLabel1.setText(s1);
objButton1.addMouseListener(new MyMouseListener()); //line 29
objFrame.add(objLabel1);
objFrame.add(objButton1);
}
public class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
a++; //line 36
}
}
}
When compiling, I get two errors. One error is on line 29, which is "non-static variable this cannot be referenced from a static context", and the other is on line 36, which is "cannot find symbol".
So, what exactly am I doing wrong? I would appreciate responders telling exactly what I need to do to fix the problem, and avoiding using technical terms since I'm rather new to programming.
I see two issues, namely your inner class should be static (to use it without an instance of option1 which should probably be Option1 to fit with Java naming conventions) and you need to define and initialize a. Something like
public static class MyMouseListener extends MouseAdapter {
int a = 0; //<-- add this.
public void mouseClicked(MouseEvent me) {
a++;
}
}
Also, I suggest you consider using the more modern JFrame instead of the older Frame.
Edit
You'll need to save a reference to your MouseListener like
MyMouseListener mml = new MyMouseListener();
objButton1.addMouseListener(mml);
Then you can get it the a like
System.out.println(mml.a);
Finally, your original approach of "" + a would be "0".
Generally, as soon as you possibly can, get out of the main method into a non-static context...
public class option1 extends Frame {
private int a = 0;
private Label objLabel1;
option1() {
setTitle("Final Project Option 1");
setSize(300,300);
Button objButton1;
objButton1 = new Button("Button");
objLabel1 = new Label();
objLabel1.setBounds(150,220,50,30);
objButton1.setBounds(40,35,50,50);
objLabel1.setText(Integer.toString(a));
objButton1.addMouseListener(new MyMouseListener()); //line 29
add(objLabel1);
add(objButton1);
show();
}
public static void main(String[] args) {
option1 test = new option1();
}
public class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
a++; //line 36
objLabel1.setText(Integer.toString(a));
}
}
}
Generally speaking, AWT is out-of-date (by some 15 years) and you really should be trying to use Swing or JavaFX instead.
Buttons should use ActionListener, as a mouse is not the only way a button might be triggered
You might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others
I just tried to make your code working. But there is some issues regarding the standard Java coding. But you should consider previous answers concerning the coding style.
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class Main {
public static void main(String[] args) {
final Frame mainFrame = new OptionOne();
Button button = new Button("Button");
final Label label = new Label();
label.setBounds(150, 220, 50, 30);
label.setText("0");
button.setBounds(40, 35, 50, 50);
label.addPropertyChangeListener(label.getText(), new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
mainFrame.addNotify();
}
});
button.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
int value = Integer.parseInt(label.getText());
label.setText(String.valueOf(value + 1));
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
mainFrame.add(label);
mainFrame.add(button);
}
}
class OptionOne extends Frame {
OptionOne() {
setTitle("Final Project Option 1");
setSize(300, 300);
show();
}
}
I'm trying to use a timer to change the position of a JLabel, from one spot on my JPanel to another. I'm not sure if I could use say .getLocation(), then change only the horizontal x value, and finally use .setLocation() to effectively modify the JLabel. I've also used .getBounds and .setBounds, but am still unsure how I can obtain the old horizontal x value to change and reapply to the new x value.
The code I tried looks something like this, but neither is a valid way to change the position of the JLabel.
// mPos is an arraylist of JLabels to be moved.
for(int m = 0; m < mPos.size(); m++){
mPos.get(m).setLocation(getLocation()-100);
}
or
for(int m = 0; m < mPos.size(); m++){
mPos.get(m).setBounds(mPos.get(m).getBounds()-100);
}
If I could just get the position of the horizontal x value I can change the position of the label.
Try with Swing Timer if you are looking for some animation.
Please have a look at How to Use Swing Timers
Here is the sample code:
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
Find a Sample code here
Sample code: (Move Hello World message 10px horizontally left to right at interval of 200 ms)
private int x = 10;
...
final JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Hello World", x, 10);
}
};
int delay = 200; // milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
x += 10;
if (x > 100) {
x = 10;
}
panel.repaint();
}
};
new Timer(delay, taskPerformer).start();
I made a similar example just so you can get the basic jest of it, try copy pasting this in a new class called "LabelPlay" and it should work fine.
import java.awt.EventQueue;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class LabelPlay {
private JFrame frame;
private JLabel label;
private Random rand;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
LabelPlay window = new LabelPlay();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public LabelPlay() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 659, 518);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
label = new JLabel("YEEEHAH!");
label.setBounds(101, 62, 54, 21);
frame.getContentPane().add(label);
JButton btnAction = new JButton("Action!");
rand = new Random();
btnAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int a = rand.nextInt(90)+10;
int b = rand.nextInt(90)+10;
int c = rand.nextInt(640)+10;
int d = rand.nextInt(500)+10;
label.setBounds(a, b, c, d);
}
});
btnAction.setBounds(524, 427, 89, 23);
frame.getContentPane().add(btnAction);
}
}
If you want this to happen in a loop at certain times, you can just put it in a loop and use Thread.sleep(amount of miliseconds) in the loop before you run the code.
Why don't you create a JLabel at position a, set it to visible, and another one at position b, setting it to not visible? After the timer is up, hide the first and show the second.
Are you planning on creating some moving imageIcon for some type of game? Or some label that moves pretty much everywhere ?
I would use an Absolute Layout and set Location manually everytime.
myPanel.setLayout(null);
// an initial point
int x = 100;
int y =100;
while (
//some moving pattern
x++; // 1 pixel per loop
y+=2; // 2 pixels per loop
myLabel.setLocation(x,y);
}
Currently i'm trying to have java hold down a key like follows:
Robot rob;
rob.keyPress(KeyEvent.VK_ENTER);
Thread.sleep(3000);
rob.keyRelease(KeyEvent.VK_ENTER);
This should hold enter down for 3 seconds, causing the repeating effect after a second or so. In other words, if you were to manually hold the "r" key, it would first type r, and then after about a second it would go like rrrrrrrr. I want this effect from the robot. I also tried:
curTime = System.currentTimeMillis();
while(System.currentTimeMillis() - curTime < duration)
{
rob.keyPress(whatever);
}
rob.keyRelease(whatever);
This, however, is extremely sensitive and a duration of 1 second outputs... well, as many whatever's as your computer can in 1 second. Thousands of lines worth. This is not my intention. Any ideas? Thanks!
P.S. The reason I want this behavior is because im writing a little scripting language to automate games with. If I want to hold the up arrow key like a normal person, I think that I need the behavior i'm talking about.
Edit:
Since there seems to be some confusion, I appologize. Let me elaborate. In my first code peice, if I choose "r" to be the character, it will just print ONE r regardless of the duration. If you, on your keyboard, press "r" for 5 seconds, it will go -> r...rrrrrrrrrrrrrrr where ... means like a second of time. That is the behavior I want, but I wont get it. The second code is where I try to spam click "press", but this literally types "r" EVERY time it executes. So if I am in a timed loop for a duration, every time that loop iterates it will send the "r" button. That's not what I want. What I want, again , is the same result that would happen as if you pushed r down on your keyboard for 3 seconds. First its just one r, and then rrrrrrrrrrrrrrrrrrrrr. I'm not even sure what the release() method does... I figured if you left it on press without release, it would just SPAM the screen in a loop! Why wouldnt it, the key is PRESSED? This is what is confusing me. Apparently when a key is pressed it doesnt STAY pressed.
If I understand your problem, you can't get key repeats to occur when using Robot and keyPress.
In this case, you may need to produce a "psudo" "long" key press.
Basically, I tried something like this:
Robot bot = new Robot();
bot.setAutoDelay(1);
int duration = 3000;
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < duration) {
bot.keyPress(KeyEvent.VK_R);
bot.keyRelease(KeyEvent.VK_R);
}
Which, rapidly pressed and releases the key over a period of time...
And I used this to test it...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestRobot {
public static void main(String[] args) {
new TestRobot();
}
public TestRobot() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea ta;
public TestPane() {
setLayout(new BorderLayout());
ta = new JTextArea(20, 20);
ta.setWrapStyleWord(true);
ta.setLineWrap(true);
add(new JScrollPane(ta));
JButton btn = new JButton("Start");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ta.requestFocusInWindow();
ta.append("Start\n");
SwingWorker worker = new SwingWorker<Object, Object>() {
#Override
protected Object doInBackground() throws Exception {
Robot bot = new Robot();
bot.setAutoDelay(1);
int duration = 3000;
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < duration) {
bot.keyPress(KeyEvent.VK_R);
bot.keyRelease(KeyEvent.VK_R);
}
return null;
}
#Override
protected void done() {
ta.append("\nDone");
}
};
worker.execute();
}
});
add(btn, BorderLayout.SOUTH);
}
}
}
Updated
With a little testing, I was able to get this to work...
Robot bot = new Robot();
bot.setAutoDelay(50);
int duration = 3000;
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < duration) {
bot.keyPress(KeyEvent.VK_R);
}
bot.keyRelease(KeyEvent.VK_R);
Now, if you play around with the autoDelay property, you can adjust the time (in milliseconds) between each event, which may produce a more desirable effect...
Why not use a for loop?
for (int i = 0; i < 10; i++)
rob.keyPress(whatever);
Or, to emulate the hold down effect you want:
rob.keyPress(whatever);
Thread.sleep(500);
for (int i = 0; i < 10; i++) {
rob.keyPress(whatever);
Thread.sleep(10);
}
If you want more "organic" behaviour, just randomize the number of iterations.