Thursday, April 7, 2011

Difficulty removing all components from a Jpanel

G'day all,

I am coding a main menu for a project. The menu displays properly. I have also set up ActionListeners for the three buttons on the menu.

What I wish to do is reuse the JPanel for a new set of radio buttons when the user chooses "Start a New Game".

However, coding ActionPerformed to remove the existing components from the JPanel has me stumped. I know removeAll is somehow important, but unfortunately NetBeans informs me I cannot call it on my mainMenu JPanel object within ActionPerformed. So i have commented it out in my code below, but left it in so you can see what I am trying to do.

Your thoughts or hints are appreciated.

Here is my main code:

public class Main {

    public static void main(String[] args) {
        MainMenu menu = new MainMenu();
        menu.pack();
        menu.setVisible(true);
    }
}

Here is my mainMenu code:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

    public class MainMenu extends JFrame implements ActionListener {
        JButton startNewGame = new JButton("Start a New Game");
        JButton loadOldGame = new JButton("Load an Old Game");
        JButton seeInstructions = new JButton("Instructions");

        public MainMenu() {
            super("RPG Main Menu");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel mainMenu = new JPanel();
            mainMenu.setLayout(new FlowLayout());
            startNewGame.setMnemonic('n');
            loadOldGame.setMnemonic('l');
            seeInstructions.setMnemonic('i');
            startNewGame.addActionListener(this);
            loadOldGame.addActionListener(this);
            seeInstructions.addActionListener(this);
            mainMenu.add(startNewGame);
            mainMenu.add(loadOldGame);
            mainMenu.add(seeInstructions);
            setContentPane(mainMenu);

        }

        public void actionPerformed(ActionEvent evt) {
            Object source = evt.getSource();
            if (source == startNewGame) {
                // StartNewGame code goes here
                // mainMenu.removeAll();
            }
            if (source == loadOldGame) {
                // LoadOldGame code goes here
            }
            if (source == seeInstructions) {
                // Quit code goes here
            }
        }
    }
From stackoverflow
  • You don't have a reference to mainMenu actionPerformed use. If you declare mainMenu with the buttons. It would work.

  • You need mainMenu to be a member variable:

     public class MainMenu extends JFrame implements ActionListener {
            JButton startNewGame = new JButton("Start a New Game");
            JButton loadOldGame = new JButton("Load an Old Game");
            JButton seeInstructions = new JButton("Instructions");
            JPanel mainMenu = new JPanel();
    

    Why do you feel the need to re-use this object?

  • The problem is that the actionPerformed method is trying to call the JPanel mainMenu which is out of scope, i.e. the mainMenu variable is not visible from the actionPerformed method.

    One way to get around this is to have the JPanel mainMenu declaration in the class itself and make it an instance field which is accessible to all instance methods of the class.

    For example:

    public class MainMenu extends JFrame implements ActionListener
    {
        ...
        JPanel mainMenu;
    
        public MainMenu()
        {
            ...
            mainMenu = new JPanel();
            ...
        }
    
        public void actionPerformed(ActionEvent e)
        {
            ...
            mainMenu.removeAll();
        }
    }
    
  • Consider using a CardLayout instead, which manages two or more components (usually JPanel instances) that share the same display space. That way you don't have to fiddle with adding and removing components at runtime.

    elwynn : Thanks Zach. I will consider CardLayout.
  • Avoid attempting to "reuse" stuff. Computers are quite capable of tidying up. Concentrate on making you code clear.

    So instead of attempting to tidy up the panel, simply replace it with a new one.

    Generally a better way to write listeners is as anonymous inner classes. Code within these will have access to final variables in the enclosing scope and to members of the enclosing class. So, if you make mainMenu final and you ActionListeners anonymous inner classes, your code should at least compile.

    Also don't attempt to "reuse" classes. Try to make each class do one sensible thing, and avoid inheritance (of implementation). There is almost never any need to extend JFrame, so don't do that. Create an ActionListener for each action, rather than attempting to determine the event source.

    Also note, you should always use Swing components on the AWT Event Dispatch Thread. Change the main method to add boilerplate something like:

    public static void main(final String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
            runEDT();
        }});
    }
    

scripty (scriptaculous) draggable onEnd not executing in Safari

hey all,

i've created a very iphone-y slider element that is both restricted in overall movement horizontally (0-400px and it does not move vertically) and "snaps" to either side of the 400px "container" when it has passed the 200px mark and the drag has ended. It works perfect in firefox. In Safari, the onEnd function that positions the element to either end of this 400px container, is never called. Whats more, the draggable element "sticks" to the mouse cursor and i have to reload the page to end the animation.

Here's my code

<div style="width:100px;height: 60px;background-color:#000;z-index:999" id="dragtest" />
<script language="JavaScript" type="text/javascript">
new Draggable('dragtest', { constraint: 'horizontal',
 onEnd: function(e, me) {
  console.debug("!!!")
  element = e.element
  x = element.style.left
  x = x.gsub('px','')

  if (x >= 200) {
   $('dragtest').style.left = 400+'px';

  }

  if (x < 200) {
   $('dragtest').style.left = 0+'px';
  }

  console.debug("Snapping to ", element.style.left, " (x was ", x, ")")
  return true;

    },
 snap: function(x, y) {
  ret_x = x
  ret_y = y

  if (x >= 400) {
   ret_x = 400
  }

  if (x <= 0) {
   ret_x = 0
  }

  return [ret_x,ret_y]

 }
});
</script>

thanks! andrew

From stackoverflow
  • For your future reference (couldnt google anything out of this), uncommenting console.debug() calls from within the onEnd handler resolved this. Weird.

    Cory R. King : Do you mean commenting out console.debug()? If you use firebug, go to their website and make sure to use their stub file which defines functions like "console.debug()" so browsers /w-out firebug don't blow up.
    pgn : Thanks, i did have firebug-lite loaded though..

Java newbie: inheritance and where to declare an intended universal object

G'day all, I have a Player class, which inherits from an ArmedHumanoids class, which inherits in turn from a Humanoids class.

Where and when should I create the Player object so that it is accessible in all my other classes - for example, a selectPlayerRace class?

I know that by extending the Player class it becomes accessible, but I am thwarted because all my other classes extend JFrame. There can be only one extension, not two.

At the moment the NetBeansIDE complains that it cannot locate the Player object when I code for it in selectPlayerRace, after creating the Player object in my Main class.

Obviously, it is happier when I create the Player object in the selectPlayerRace class, but then I can't access the Player object in all my other classes as it is internal to selectPlayerRace.

The Player object is intended to be a universal object accessible in all my other classes. I'm sorry for this dreadfully newbieish question, but I can't figure it out.

From stackoverflow
  • It sounds like you are looking for a static declaration here. As I understand it you want to get a global access to some instance of Player but would not need to extend some other class or implement some interface to do so (which means you don't have to inherit any behaviour, you just want access to one object). You could store the Player instance you want to access static e.g. in a PlayerManagement class. You then put a static method in it like getPlayer(String playerName) which synchronizes access to its array/Vector/whatever containing all Player objects and then returns the object in question (or null if not found). You can link your humanoid-classes into PlayerManagement and vice versa.

    Maybe you also want a Player interface. You can implement as many interfaces as you like but only extend one other class but you have to reimplement all functionality since you cannot write any code into an interface, just define what attributes/methods a class implementing that interface must provide.

    Energiequant : Oooookay?! Any comment why this has been down-voted? I don't get it?
  • You can create a object of your Player class and pass it to the other objects via e.g. constructor or method which accepts Player type.

    public class Entry
    {
       public static void main(string[] args)
       {
          // initialize a player object
          Player player=new Player("elwynn");
          // initialize some other object which requires player object.
          // since player object needs to be accessed within foo.
          Foo foo = new Foo(player);
          // you are about to use player object within foo.
          foo.MakePlayerPlay(); 
       } 
    } 
    
    public class Foo
    {
    
      Player player;
      public Foo(Player p)
      {
       this.player = p;
      }
    
      public void MakePlayerPlay()
      {
        // you are using player object here
        // which is the same instance you created 
        // within main() in Entry class.
        if(this.player!=null) this.player.play();
      }
    
    }
    
  • It is bad style to have global objects, because this

    • will make testing more difficult, and

    • will cause problems when there arises a need to have more than one instances.

    It is better to give references to other objects on construction (this is called dependency injection) on a need-to-know basis, or where appropriate to pass references by parameter.

    That said, look up the Singleton design pattern.

    Tom Hawtin - tackline : Look up the singleton antipattern, and make a note never to use it.
  • The Player object is intended to be a universal object accessible in all my other classes.

    Why not just pass this Player object in the constructor of the other classes, or in the methods that you call?

  • This sounds like a singleton pattern.

    public class Player extends ArmedHumanoid {
    
      private static Player instance = new Player();
    
      private Player() {}
    
      public static Player getIntstance() {
        return instance
      }
    
    }
    

    Then any class can call Player.getInstance() to get access to the Player object.

    elwynn : That is exactly the solution I needed. It works perfectly in my code. For example, I can call Player.getInstance.classType = "Mage" in the selectClassType class. Thank you so much for solving this problem for me.

A WCF service behind a firewall generates a wrong wsdl URI

Hi, I developed a WCF service and i have published it with IIS. All goes well inside the local network but when the service is accessed by an external client from the internet, redirected by a firewall, the service generates a local wsdl uri that cannot be solve by the client.

Something like this:

  • URI needed: http://external_url/service.svc?wsdl
  • URI created: http://internal_url/service.svc?wsdl

I would like to continue using the automatic generation of the wsdl file without indicating an external path. I also have prove manipulating the ServiceBehavior attribute into the service class but the problem persists.

How can I do it?

From stackoverflow

REXML preserve attributes order

I try to generate such XML using REXML

<root>
  <add key='foo' value='bar'/>
</root>

But what I get is (notice that key/value order)

<root>
  <add value='bar' key='foo'/>
</root>

Code:

require 'rexml/document'
include REXML

doc = Document.new
doc.add_element('root')
el = doc.root.add_element('add')
el.add_attribute('key', 'foo')
el.add_attribute('value', 'bar')
puts doc

It does not matter if I write:

el.add_attribute('key', 'foo')
el.add_attribute('value', 'bar')

or

el.add_attribute('value', 'bar')
el.add_attribute('key', 'foo')

result is the same. Looks like REXML uses some dictionary to keep the attributes...

Can I enforce the desired order: key/value?

From stackoverflow
  • In XML, it doesn't matter what order the attributes are in. If you have some piece of XML processing code where it does matter, then I would suggest that code was buggy.

    From the XML spec here, note the phrase: "Note that the order of attribute specifications in a start-tag or empty-element tag is not significant".

    In answer to your specific question on whether you can enforce a certain order, I don't believe so. I've never actually tried to do it (since it's unnecessary) but it seems unlikely the REXML people would waste time implementing such a non-feature :-). Since the key/value pairs are stored as a hash, their order is likely to be random (as far as you could tell from the alphabetic sequence of the keys).

    Of course, since Ruby comes with the source code for REXML, you could (if desperate) replace or augment the included copy with your own version (REXML2 ?).

    Since you're doing a simple puts, it's probably using the pretty formatter so check the start of the write_element code in src/rexml/formatters/pretty.rb where it performs the "node.attributes.each_attribute do |attr|" - you may find it's as simple as sorting that list before processing the elements.

    You may also want to suggest to the developers (see here for the mailing list or here for bug reports and enhancement requests) that they make this an option in a future release but, if I were them, I'd simply say it was unnecessary.

    alex2k8 : Sure, the order does not matter from machine perspective. I need it for readability only. Actually I have to modify config file, and whould like to preserve formatting as much as possible.
    paxdiablo : See updates on possible approaches (basically either forking for local use or trying to convince developers to add this feature).
  • If you're modifying a config file and formatting is important, then it might be easier to read it in via REXML but modify via regexps.

    Also, keep in mind that generating a lot of XML via REXML is incredibly slow. I had a site that had to both read and write a lot of XML; I found that for reading, REXML was fast enough, but for writing I had to use libxml. And actually, libxml was such a bear to install and the ruby libraries for it so immature, that I ended up using erb to just replace certain parts of already-written XML docs.

    Good luck!

MySQL Great Circle Distance (Haversine formula)

Hello All, I've got a PHP script that gets Longitude and Latitude values...then inputs them into a MySQL query. I'd really like to make it solely MySQL.

Live site can be found at http://MotoListr.com

Here's my current PHP Code:

if ($distance != "Any" && $customer_zip != "") { //get the great circle distance

    //get the origin zip code info
    $zip_sql = "SELECT * FROM zip_code WHERE zip_code = '$customer_zip'";
    $result = mysql_query($zip_sql);
    $row = mysql_fetch_array($result);
    $origin_lat = $row['lat'];
    $origin_lon = $row['lon'];

    //get the range
    $lat_range = $distance/69.172;
    $lon_range = abs($distance/(cos($details[0]) * 69.172));
    $min_lat = number_format($origin_lat - $lat_range, "4", ".", "");
    $max_lat = number_format($origin_lat + $lat_range, "4", ".", "");
    $min_lon = number_format($origin_lon - $lon_range, "4", ".", "");
    $max_lon = number_format($origin_lon + $lon_range, "4", ".", "");
    $sql .= "lat BETWEEN '$min_lat' AND '$max_lat' AND lon BETWEEN '$min_lon' AND '$max_lon' AND ";
    }

Does anyone know how to make this entirely MySQL? I've browsed the internet a bit but most of the literature on it is pretty confusing.

Best, Nick

From stackoverflow
  • From Google Code FAQ - Creating a Store Locator with PHP, MySQL & Google Maps:

    Here's the SQL statement that will find the closest 20 locations that are within a radius of 25 miles to the 37, -122 coordinate. It calculates the distance based on the latitude/longitude of that row and the target latitude/longitude, and then asks for only rows where the distance value is less than 25, orders the whole query by distance, and limits it to 20 results. To search by kilometers instead of miles, replace 3959 with 6371.

    SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance 
    FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
    
  • $greatCircleDistance = acos( cos($latitude0) * cos($latitude1) * cos($longitude0 - $longitude1) + sin($latitude0) * sin($latitude1));

    with latitude and longitude in radian.

    so

    SELECT 
      acos( 
          cos(radians( $latitude0 ))
        * cos(radians( $latitude1 ))
        * cos(radians( $longitude0 ) - radians( $longitude1 ))
        + sin(radians( $latitude0 )) 
        * sin(radians( $latitude1 ))
      ) AS greatCircleDistance 
     FROM yourTable;
    

    is your sequel query

    to get your results in Km or miles, multiply the result with the mean radius of Earth (3959 miles, 6371 Km or 3440 nautical miles)

    The thing you are calculating in your example is a bounding box. If you put your coordinate data in a spatial enabled MySQL column, you can use MySQL's build in functionality to query the data.

    SELECT 
      id
    FROM spatialEnabledTable
    WHERE 
      MBRWithin(ogc_point, GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'))
    
  • Using the above formula I am getting big difference in distance ... The distance using maps.google.com is ~1500 but using this formula its 1240.. Can anybody tell why is this ?

    Thanks

    Pavel Chuchuva : Please ask a separate question. You can put link to your question here, as comment to the answer.

Why does Consolas in Visual Studio look bold?

I have tried installing the Consolas font pack so that I can use it with VS 2005. For some reason it looks a lot bolder than Wikipedia's and Jeff Atwood's examples. I read something about anti-aliasing and I am trying that now. Any ideas on how to get it too look thin and sleak?

EDIT: Sorry found out. It has something to do with ClearType fonts. Turning it on sorted out all my problems.

From stackoverflow
  • Did you make sure you have ClearType activated?

  • It looks bolder when your Windows OS (XP?) has Font smoothing turned on.

    Right click your Desktop > Properties > Appearance tab > Effects > "Use the following method to smoothe screen fonts".

    Try changing it to ClearType / Standard / Turn it off. Keep switching back to VS and scroll up/down a bit to see the effect.

  • You can turn on the clearType by running through the wizard from MS website below,

    http://www.microsoft.com/typography/cleartype/tuner/step1.aspx