Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7699635
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T22:31:31+00:00 2026-05-31T22:31:31+00:00

I’m making a piano application in Java. This is one of the functions, public

  • 0

I’m making a piano application in Java. This is one of the functions,

public void playOnce(int time) {
    play();
    doClick(time);
    stop();
}

public void play() {
    channel[0].noteOn(note, 60);
}

public void stop() {
    channel[0].noteOff(note);
}

I’ll provide a minimal working example if necessary, but I wanted to make sure it’s not an obvious issue. The problem is that playOnce is called in a while loop. playOnce is in a Key class, and each Key has a different note. In each iteration of the while loop, playOnce is called on a different key. Once all the keys have been played, it stops.

The doClick method correctly pressed the key, but it’s not released until all the keys have been played. In fact, while the keys are being played, you can’t do anything, even press the pause button. For this problem, I guess I could put the entire loop in a different thread, but I don’t think that type of solution will allow the key to be released.

EDIT: Yea, I figured out I need a new thread to get other actions to work, but I still need a fix for doClick(). This might be more complicated than I thought so here’s a working example,

Main.java

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.DecimalFormat;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;

public class Main implements ActionListener {

    final int WHITE_KEY_WIDTH, WHITE_KEY_HEIGHT, BLACK_KEY_WIDTH,
            BLACK_KEY_HEIGHT;
    final int WIDTH;
    final JFileChooser fc;
    {
        WHITE_KEY_WIDTH = Key.WHITE_KEY_WIDTH;
        BLACK_KEY_WIDTH = Key.BLACK_KEY_WIDTH;
        WHITE_KEY_HEIGHT = Key.WHITE_KEY_HEIGHT;
        BLACK_KEY_HEIGHT = Key.BLACK_KEY_HEIGHT;
        WIDTH = 3 * (WHITE_KEY_WIDTH * 7) + WHITE_KEY_WIDTH;
        fc = new JFileChooser();
    }

    public static Key keys[] = new Key[48];
    private static int index = 0;
    private String prevText = "";

    JTextArea shabadEditor = null;
    JSpinner tempoControl;
    JFrame frame;
    File curFile;

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        frame = new JFrame();

        JPanel mainPanel = new JPanel();
        JPanel controlPanel = new JPanel();
        JLayeredPane pianoPanel = new JLayeredPane();

        mainPanel.setLayout(new GridBagLayout());

        JButton playButton = new JButton("Play");
        JButton pauseButton = new JButton("Pause");

        playButton.addActionListener(this);
        playButton.setActionCommand("play");

        pauseButton.addActionListener(this);
        pauseButton.setActionCommand("pause");

        SpinnerNumberModel model = new SpinnerNumberModel(1, 0, 2, .1);
        tempoControl = new JSpinner(model);
        JSpinner.NumberEditor editor = (JSpinner.NumberEditor) tempoControl
                .getEditor();
        DecimalFormat format = editor.getFormat();
        format.setMinimumFractionDigits(1);
        Dimension d = tempoControl.getPreferredSize();
        d.width = 40;
        tempoControl.setPreferredSize(d);

        GridBagConstraints c = new GridBagConstraints();
        // Construct each top level component
        controlPanel.add(playButton);
        controlPanel.add(pauseButton);
        controlPanel.add(tempoControl);
        shabadEditor = new JTextArea(20, 78);
        constructKeyboard(pianoPanel);

        // Add the piano panel and shabad editor to the window
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1.0;
        c.anchor = GridBagConstraints.NORTHWEST;
        mainPanel.add(controlPanel, c);

        c.gridx = 0;
        c.gridy = 1;
        c.weightx = 1.0;
        // c.weighty = 1.0;
        c.anchor = GridBagConstraints.NORTHWEST;
        pianoPanel
                .setPreferredSize(new Dimension(WIDTH - 18, WHITE_KEY_HEIGHT));
        mainPanel.add(pianoPanel, c);

        c.gridx = 0;
        c.gridy = 2;
        c.weightx = 1.0;
        c.weighty = 1.0;
        c.anchor = GridBagConstraints.NORTHWEST;
        mainPanel.add(shabadEditor, c);
        frame.add(mainPanel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH, WHITE_KEY_HEIGHT * 3 + 30);
        frame.setLocation(250, 60);
        frame.setVisible(true);
    }

    void constructKeyboard(Container panel) {
        int i = 0;
        int j = 0;

        for (int k = 0; k < 3; k++) {
            addWhiteKey(panel, i++);
            addBlackKey(panel, j++);
            addWhiteKey(panel, i++);
            addBlackKey(panel, j++);
            addWhiteKey(panel, i++);
            addWhiteKey(panel, i++);
            j++;
            addBlackKey(panel, j++);
            addWhiteKey(panel, i++);
            addBlackKey(panel, j++);
            addWhiteKey(panel, i++);
            addBlackKey(panel, j++);
            j++;
            addWhiteKey(panel, i++);
        }
    }

    void addWhiteKey(Container panel, int i) {
        WhiteKey b = new WhiteKey();
        b.setLocation(i++ * WHITE_KEY_WIDTH, 0);
        panel.add(b, 0, -1);
        keys[index++] = b;
    }

    void addBlackKey(Container panel, int factor) {
        BlackKey b = new BlackKey();
        b.setLocation(WHITE_KEY_WIDTH - BLACK_KEY_WIDTH / 2 + factor
                * WHITE_KEY_WIDTH, 0);
        panel.add(b, 1, -1);
        keys[index++] = b;
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        String action = arg0.getActionCommand();

        if (action.equals("play")) {
            System.out.println("working");
            for (int i = 0; i < 10; i++) {
                keys[i].playOnce(500);
            }
        }
    }
}

Key.java

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Synthesizer;
import javax.swing.JButton;

public class Key extends JButton implements MouseListener {

    private static final long serialVersionUID = 1L;

    public static final int WHITE_KEY_HEIGHT = 200;
    public static final int WHITE_KEY_WIDTH = 40;
    public static final int BLACK_KEY_WIDTH = 20;
    public static final int BLACK_KEY_HEIGHT = 120;

    private static int noteCount = 40;
    public int note;

    private static Synthesizer synth = null;

    static {
        try {
            synth = MidiSystem.getSynthesizer();
            synth.open();
        } catch (MidiUnavailableException e) {
            e.printStackTrace();
        }
    }
    MidiChannel channel[];

    public Key() {
        note = noteCount++;

        // Instrument[] instruments = synth.getAvailableInstruments();
        // for (Instrument instrument : instruments) {
        // System.out.println(instrument.getName());
        // System.out.println(instrument.getPatch().getBank());
        // System.out.println(instrument.getPatch().getProgram());
        // }

        channel = synth.getChannels();
        channel[0].programChange(20);
        addMouseListener(this);
    }

    public void playOnce(int time) {
        play();
        doClick(time);
        stop();
    }

    public void play() {
        channel[0].noteOn(note, 60);
    }

    public void stop() {
        channel[0].noteOff(note);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println(this.note);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {
        play();

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        stop();
    }

}

BlackKey.java

import java.awt.Color;

public class BlackKey extends Key {

    private static final long serialVersionUID = 1L;

    public BlackKey() {
        super();
        setBackground(Color.BLACK);
        setSize(BLACK_KEY_WIDTH, BLACK_KEY_HEIGHT);
    }
}

WhiteKey.java

import java.awt.Color;

public class WhiteKey extends Key {

    private static final long serialVersionUID = 1L;

    public WhiteKey() {
        super();
        setBackground(Color.WHITE);
        setSize(WHITE_KEY_WIDTH, WHITE_KEY_HEIGHT);
    }

}

EDIT: After doing a bit of work with threading, this is what I have

By putting the for loop in another thread, the keys are released at the right time:

@Override
    public void actionPerformed(ActionEvent arg0) {
        String action = arg0.getActionCommand();

        if (action.equals("play")) {
            System.out.println("working");
            new Thread(new Runnable() {
                public void run() {
                    for (int i = 0; i < 20; i++) {
                        keys[i].playOnce(100);
                    }
                }
            }).start();
        }
    }
}

The issue now is that the keyboard glitches. The keyboard is created using a layered pane, and for some reason when the keys are released the layers that are supposed to be on the bottom come to the top. When I hover my mouse over them, the glitch goes away. Any ideas?

EDIT2: I fixed the glitches. I simply had to add

     try {
        Thread.sleep(10);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

after doClick();

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T22:31:32+00:00Added an answer on May 31, 2026 at 10:31 pm

    The problem with your approach is that you are blocking the event thread. This thread is responsible for user input, painting and window updates. My guess is now, that doClick‘s timeout gets checked inside the event thread (seems logical), so it won’t get released until your actionPerformed method exits (and so the event thread can continue its event processing).

    A solution to this problem would be (as you already mentioned) moving your for loop to another thread and call doClick using SwingUtilities.invokeLater.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I'm making a simple page using Google Maps API 3. My first. One marker
link Im having trouble converting the html entites into html characters, (&# 8217;) i
For some reason, after submitting a string like this Jack’s Spindle from a text
this is what i have right now Drawing an RSS feed into the php,
I am reading a book about Javascript and jQuery and using one of the
I have this code to decode numeric html entities to the UTF8 equivalent character.
I want use html5's new tag to play a wav file (currently only supported

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.