diff --git a/data/maps/Africa.fsm b/data/maps/Africa.fsm deleted file mode 100644 index 8ee6eeef94..0000000000 Binary files a/data/maps/Africa.fsm and /dev/null differ diff --git a/data/maps/America_large.fsm b/data/maps/America_large.fsm deleted file mode 100644 index 7db554f503..0000000000 Binary files a/data/maps/America_large.fsm and /dev/null differ diff --git a/data/maps/Australia.fsm b/data/maps/Australia.fsm deleted file mode 100644 index 49ce6a5574..0000000000 Binary files a/data/maps/Australia.fsm and /dev/null differ diff --git a/data/maps/Caribbean_basin.fsm b/data/maps/Caribbean_basin.fsm deleted file mode 100644 index 37a1c9ed5e..0000000000 Binary files a/data/maps/Caribbean_basin.fsm and /dev/null differ diff --git a/data/maps/Caribbean_large.fsm b/data/maps/Caribbean_large.fsm deleted file mode 100644 index ba0743b543..0000000000 Binary files a/data/maps/Caribbean_large.fsm and /dev/null differ diff --git a/data/maps/L_America_JsTheDude.fsm b/data/maps/L_America_JsTheDude.fsm new file mode 100644 index 0000000000..6c385178f9 Binary files /dev/null and b/data/maps/L_America_JsTheDude.fsm differ diff --git a/data/maps/L_America_Mazim.fsm b/data/maps/L_America_Mazim.fsm new file mode 100644 index 0000000000..18d168979c Binary files /dev/null and b/data/maps/L_America_Mazim.fsm differ diff --git a/data/maps/L_Asia_Mazim.fsm b/data/maps/L_Asia_Mazim.fsm new file mode 100644 index 0000000000..6ce32e74b0 Binary files /dev/null and b/data/maps/L_Asia_Mazim.fsm differ diff --git a/data/maps/L_PacificSouth_Mazim.fsm b/data/maps/L_PacificSouth_Mazim.fsm new file mode 100644 index 0000000000..8a8beaf9c2 Binary files /dev/null and b/data/maps/L_PacificSouth_Mazim.fsm differ diff --git a/data/maps/L_TheOldWorld_Mazim.fsm b/data/maps/L_TheOldWorld_Mazim.fsm new file mode 100644 index 0000000000..637ee1b333 Binary files /dev/null and b/data/maps/L_TheOldWorld_Mazim.fsm differ diff --git a/data/maps/M_Africa_Gilolat.fsm b/data/maps/M_Africa_Gilolat.fsm new file mode 100644 index 0000000000..929d03081a Binary files /dev/null and b/data/maps/M_Africa_Gilolat.fsm differ diff --git a/data/maps/M_Africa_Mazim.fsm b/data/maps/M_Africa_Mazim.fsm new file mode 100644 index 0000000000..4c96f62cf5 Binary files /dev/null and b/data/maps/M_Africa_Mazim.fsm differ diff --git a/data/maps/M_America_Mazim.fsm b/data/maps/M_America_Mazim.fsm new file mode 100644 index 0000000000..f0f53cdaa8 Binary files /dev/null and b/data/maps/M_America_Mazim.fsm differ diff --git a/data/maps/M_AustraliaOceania_Mazim.fsm b/data/maps/M_AustraliaOceania_Mazim.fsm new file mode 100644 index 0000000000..00b22954af Binary files /dev/null and b/data/maps/M_AustraliaOceania_Mazim.fsm differ diff --git a/data/maps/M_CaribbeanIslands_Mazim.fsm b/data/maps/M_CaribbeanIslands_Mazim.fsm new file mode 100644 index 0000000000..9b736bc675 Binary files /dev/null and b/data/maps/M_CaribbeanIslands_Mazim.fsm differ diff --git a/data/maps/M_Caribbean_Piotrus.fsm b/data/maps/M_Caribbean_Piotrus.fsm new file mode 100644 index 0000000000..5aeb5e1c4b Binary files /dev/null and b/data/maps/M_Caribbean_Piotrus.fsm differ diff --git a/data/maps/M_Eurasia_Mazim.fsm b/data/maps/M_Eurasia_Mazim.fsm new file mode 100644 index 0000000000..301da95963 Binary files /dev/null and b/data/maps/M_Eurasia_Mazim.fsm differ diff --git a/data/maps/M_NorthAmerica2_Mazim.fsm b/data/maps/M_NorthAmerica2_Mazim.fsm new file mode 100644 index 0000000000..12254f3440 Binary files /dev/null and b/data/maps/M_NorthAmerica2_Mazim.fsm differ diff --git a/data/maps/M_NorthAmerica_Mazim.fsm b/data/maps/M_NorthAmerica_Mazim.fsm new file mode 100644 index 0000000000..7bf06b8dbb Binary files /dev/null and b/data/maps/M_NorthAmerica_Mazim.fsm differ diff --git a/data/maps/M_SouthAmerica_Mazim.fsm b/data/maps/M_SouthAmerica_Mazim.fsm new file mode 100644 index 0000000000..017ee3cb9f Binary files /dev/null and b/data/maps/M_SouthAmerica_Mazim.fsm differ diff --git a/data/maps/S_Arabias_Mazim.fsm b/data/maps/S_Arabias_Mazim.fsm new file mode 100644 index 0000000000..520f80d752 Binary files /dev/null and b/data/maps/S_Arabias_Mazim.fsm differ diff --git a/data/maps/S_AustraliaOceania_Gilolat.fsm b/data/maps/S_AustraliaOceania_Gilolat.fsm new file mode 100644 index 0000000000..5c40ff2929 Binary files /dev/null and b/data/maps/S_AustraliaOceania_Gilolat.fsm differ diff --git a/data/maps/S_Caribbean_Phil.fsm b/data/maps/S_Caribbean_Phil.fsm new file mode 100644 index 0000000000..a188651215 Binary files /dev/null and b/data/maps/S_Caribbean_Phil.fsm differ diff --git a/data/maps/S_FeudalJapan_Mazim.fsm b/data/maps/S_FeudalJapan_Mazim.fsm new file mode 100644 index 0000000000..936d279ab5 Binary files /dev/null and b/data/maps/S_FeudalJapan_Mazim.fsm differ diff --git a/data/maps/S_SouthEastAsia_Mazim.fsm b/data/maps/S_SouthEastAsia_Mazim.fsm new file mode 100644 index 0000000000..c4e84d01e3 Binary files /dev/null and b/data/maps/S_SouthEastAsia_Mazim.fsm differ diff --git a/data/maps/S_USA_Mazim.fsm b/data/maps/S_USA_Mazim.fsm new file mode 100644 index 0000000000..5d77cb36c8 Binary files /dev/null and b/data/maps/S_USA_Mazim.fsm differ diff --git a/data/maps/South_America.fsm b/data/maps/South_America.fsm deleted file mode 100644 index bc9a4ab10a..0000000000 Binary files a/data/maps/South_America.fsm and /dev/null differ diff --git a/data/maps/XL_GigaEarth_Mazim.fsm b/data/maps/XL_GigaEarth_Mazim.fsm new file mode 100644 index 0000000000..0ddabd97b3 Binary files /dev/null and b/data/maps/XL_GigaEarth_Mazim.fsm differ diff --git a/data/maps/XXL_HugeWorld_Mazim.fsm b/data/maps/XXL_HugeWorld_Mazim.fsm new file mode 100644 index 0000000000..9d4511930f Binary files /dev/null and b/data/maps/XXL_HugeWorld_Mazim.fsm differ diff --git a/data/strings/FreeColMessages.properties b/data/strings/FreeColMessages.properties index d3eceec5ce..92c5991ea4 100644 --- a/data/strings/FreeColMessages.properties +++ b/data/strings/FreeColMessages.properties @@ -3545,12 +3545,29 @@ mapEditorTransformPanel.setRiverStyle=Set river style mapEditorTransformPanel.resource=Change/remove resource # MapGeneratorOptionsDialog -freecol.map.Africa=Africa -freecol.map.America_large=America (large) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Caribbean Basin -freecol.map.Caribbean_large=Caribbean (large) -freecol.map.South_America=South America +freecol.map.L_America_JsTheDude=L America
By JsTheDude +freecol.map.L_America_Mazim=L America
By Mazim +freecol.map.L_Asia_Mazim=L Asia
By Mazim +freecol.map.L_PacificSouth_Mazim=L Pacific South
By Mazim +freecol.map.L_TheOldWorld_Mazim=L The Old World
By Mazim +freecol.map.M_Africa_Gilolat=M Africa
By Gilolat +freecol.map.M_Africa_Mazim=M Africa
By Mazim +freecol.map.M_America_Mazim=M America
By Mazim +freecol.map.M_AustraliaOceania_Mazim=M Australia
Oceania
By Mazim +freecol.map.M_Caribbean_Piotrus=M Caribbean Basin
By Piotrus +freecol.map.M_CaribbeanIslands_Mazim=M Caribbean Islands
By Mazim +freecol.map.M_Eurasia_Mazim=M Eurasia
By Mazim +freecol.map.M_NorthAmerica_Mazim=M North America 2
By Mazim +freecol.map.M_NorthAmerica2_Mazim=M North
America
By Mazim +freecol.map.M_SouthAmerica_Mazim=M South
America
By Mazim +freecol.map.S_Arabias_Mazim=S Arabias
By Mazim +freecol.map.S_AustraliaOceania_Gilolat=S Australia
Oceania
By Gilolat +freecol.map.S_Caribbean_Phil=S Caribbean Basin
By Phil +freecol.map.S_FeudalJapan_Mazim=S Feudal Japan
By Mazim +freecol.map.S_SouthEastAsia_Mazim=S South East Asia
By Mazim +freecol.map.S_USA_Mazim=S USA
By Mazim +freecol.map.XL_GigaEarth_Mazim=XL Giga Earth
By Mazim +freecol.map.XXL_HugeWorld_Mazim=XXL Huge World
By Mazim mapGeneratorOptionsDialog.badWidth=Map width (%width%) is too narrow, less than 4 times edge-distance (%edge%) diff --git a/data/strings/FreeColMessages_ang.properties b/data/strings/FreeColMessages_ang.properties index 47ed78091b..02d1d83204 100644 --- a/data/strings/FreeColMessages_ang.properties +++ b/data/strings/FreeColMessages_ang.properties @@ -1969,10 +1969,6 @@ mapEditorTransformPanel.chooseResource=Ceose sceattfruman mapEditorTransformPanel.majorRiver=Hēafodēa mapEditorTransformPanel.minorRiver=Midmicel ēa mapEditorTransformPanel.resource=Andƿende oþþe anime sceattfruman. -freecol.map.Africa=Affrica -freecol.map.America_large=Ƿinland (great) -freecol.map.Australia=Suþland -freecol.map.Caribbean_basin=Caribisc Geard mapSizeDialog.mapSize=Ceose landymelan micelnesse newPanel.editDifficulty=Adihte earfoþnesse newPanel.getServerList=Fo þegntola getæl diff --git a/data/strings/FreeColMessages_ar.properties b/data/strings/FreeColMessages_ar.properties index 8f028e8acf..7a317ef011 100644 --- a/data/strings/FreeColMessages_ar.properties +++ b/data/strings/FreeColMessages_ar.properties @@ -3003,12 +3003,6 @@ mapEditorTransformPanel.minorRiver=نهر صغير mapEditorTransformPanel.changeRiverConnections=إضافة/إزالة اتصالات النهر mapEditorTransformPanel.setRiverStyle=تعيين نمط النهر mapEditorTransformPanel.resource=تغيير/إزالة المورد -freecol.map.Africa=أفريقيا -freecol.map.America_large=أمريكيا (ضخم) -freecol.map.Australia=أستراليا -freecol.map.Caribbean_basin=الحوض الكاريبي -freecol.map.Caribbean_large=الكاريبي (كبير) -freecol.map.South_America=أمريكا الجنوبية mapGeneratorOptionsDialog.badWidth=عرض الخريطة (%width%) ضيق جدا، أقل 4 أضعاف من مسافة الحافة (%edge%) mapSizeDialog.mapSize=اختر حجم الخريطة modifierFormat.unknown=؟؟؟ diff --git a/data/strings/FreeColMessages_br.properties b/data/strings/FreeColMessages_br.properties index 9d8e32d7f7..dbad6be1ce 100644 --- a/data/strings/FreeColMessages_br.properties +++ b/data/strings/FreeColMessages_br.properties @@ -3011,12 +3011,6 @@ mapEditorTransformPanel.minorRiver=Gwazh-dour mapEditorTransformPanel.changeRiverConnections=Ouzhpennañ/dilemel kevreadennoù ar stêr mapEditorTransformPanel.setRiverStyle=Termeniñ doare ar stêr mapEditorTransformPanel.resource=Kemm/dilemel danvezioù -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (ledan) -freecol.map.Australia=Aostralia -freecol.map.Caribbean_basin=Diazad ar C'harib -freecol.map.Caribbean_large=Inizi Karib (ledan) -freecol.map.South_America=Suamerika mapGeneratorOptionsDialog.badWidth=Re vihan eo ledander ar gartenn %width%, peder gwech bihanoc'h eo keit ar riblenn %edge%. mapSizeDialog.mapSize=Diuzañ ment ar gartenn modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_ca.properties b/data/strings/FreeColMessages_ca.properties index 1839e411d1..536d1212b6 100644 --- a/data/strings/FreeColMessages_ca.properties +++ b/data/strings/FreeColMessages_ca.properties @@ -3096,12 +3096,6 @@ mapEditorTransformPanel.minorRiver=Riu menor mapEditorTransformPanel.changeRiverConnections=Afegeix/retira connexions de riu mapEditorTransformPanel.setRiverStyle=Estableix el tipus de riu mapEditorTransformPanel.resource=Canvia/elimina recurs -freecol.map.Africa=Àfrica -freecol.map.America_large=Amèrica (gran) -freecol.map.Australia=Austràlia -freecol.map.Caribbean_basin=La Conca del Carib -freecol.map.Caribbean_large=Carib (gran) -freecol.map.South_America=Sud Amèrica mapGeneratorOptionsDialog.badWidth=L'amplada del mapa (%width%) és massa estreta, menys de 4 vegades la distància de la vora (%edge%) mapSizeDialog.mapSize=Selecciona la mida del mapa modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_cs_CZ.properties b/data/strings/FreeColMessages_cs_CZ.properties index aa93727db3..0c00b1d877 100644 --- a/data/strings/FreeColMessages_cs_CZ.properties +++ b/data/strings/FreeColMessages_cs_CZ.properties @@ -3018,12 +3018,6 @@ mapEditorTransformPanel.minorRiver=Říčka mapEditorTransformPanel.changeRiverConnections=Přidat/Odstranit spojení řeky mapEditorTransformPanel.setRiverStyle=Nastavit styl řeky mapEditorTransformPanel.resource=Změnit/odstranit zdroj -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (velká) -freecol.map.Australia=Austrálie -freecol.map.Caribbean_basin=Karibská oblast -freecol.map.Caribbean_large=Karibská (velká) -freecol.map.South_America=Jižní Amerika mapGeneratorOptionsDialog.badWidth=Šířka mapy (%width%) je příliš úzká, méně než čtyřikrát ve vzdálenosti od okraje (%edge%) mapSizeDialog.mapSize=Vyber velikost mapy modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_da.properties b/data/strings/FreeColMessages_da.properties index 10b604ae78..1db9fb18de 100644 --- a/data/strings/FreeColMessages_da.properties +++ b/data/strings/FreeColMessages_da.properties @@ -3015,12 +3015,6 @@ mapEditorTransformPanel.minorRiver=Lille flod mapEditorTransformPanel.changeRiverConnections=Tilføj/fjern flodforbindelser mapEditorTransformPanel.setRiverStyle=Angiv flodstil mapEditorTransformPanel.resource=Ændre/fjerne ressource -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (stor) -freecol.map.Australia=Australien -freecol.map.Caribbean_basin=Karibiske hav -freecol.map.Caribbean_large=Caribisk (stor) -freecol.map.South_America=Sydamerika mapGeneratorOptionsDialog.badWidth=Kortbredde (%width%) er for smal, mindre end 4 gange kantafstand (%edge%) mapSizeDialog.mapSize=Vælg kortstørrelse modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_de.properties b/data/strings/FreeColMessages_de.properties index 1d60d495f0..7e7dc1e10c 100644 --- a/data/strings/FreeColMessages_de.properties +++ b/data/strings/FreeColMessages_de.properties @@ -3002,12 +3002,6 @@ mapEditorTransformPanel.minorRiver=Bach mapEditorTransformPanel.changeRiverConnections=Flussverbindungen hinzufügen/entfernen mapEditorTransformPanel.setRiverStyle=Fluss-Stil festlegen mapEditorTransformPanel.resource=Ressource ändern/löschen -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (groß) -freecol.map.Australia=Australien -freecol.map.Caribbean_basin=Karibischer Becken -freecol.map.Caribbean_large=Karibik (groß) -freecol.map.South_America=Südamerika mapGeneratorOptionsDialog.badWidth=Die Kartenbreite (%width%) ist zu schmal, weniger als der vierfache Abstand zum Rand (%edge%) mapSizeDialog.mapSize=Kartengröße wählen modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_el.properties b/data/strings/FreeColMessages_el.properties index 57763c43f8..b1eead250b 100644 --- a/data/strings/FreeColMessages_el.properties +++ b/data/strings/FreeColMessages_el.properties @@ -1455,11 +1455,6 @@ loadingSavegameDialog.name=Φόρτωση Αποθηκευμένου παιχν mapEditorTransformPanel.majorRiver=Κύριος ποταμός mapEditorTransformPanel.minorRiver=Μικρός ποταμός mapEditorTransformPanel.resource=Αλλαγή/αφαίρεση πόρου -freecol.map.Africa=Αφρική -freecol.map.America_large=Αμερική (μεγάλα) -freecol.map.Australia=Αυστραλία -freecol.map.Caribbean_basin=Λεκάνη της Καραϊβικής -freecol.map.South_America=Amerique du Sud mapSizeDialog.mapSize=Επιλογή μεγέθους χάρτη newPanel.getServerList=Λήψη καταλόγου εξυπηρετητών newPanel.joinMultiPlayerGame=Συμμετοχή σε παιχνίδι πολλών παικτών diff --git a/data/strings/FreeColMessages_eo.properties b/data/strings/FreeColMessages_eo.properties index dcfef06d5d..51d1c32486 100644 --- a/data/strings/FreeColMessages_eo.properties +++ b/data/strings/FreeColMessages_eo.properties @@ -2530,12 +2530,6 @@ mapEditorTransformPanel.majorRiver=Larĝa rivero mapEditorTransformPanel.minorRiver=Mallarĝa rivero mapEditorTransformPanel.setRiverStyle=Elekti stilon de rivero mapEditorTransformPanel.resource=Ŝanĝi/forigi rimedon -freecol.map.Africa=Afriko -freecol.map.America_large=Ameriko (granda) -freecol.map.Australia=Aŭstralio -freecol.map.Caribbean_basin=Baseno Kariba -freecol.map.Caribbean_large=Karibo (Granda) -freecol.map.South_America=Sud-Ameriko mapSizeDialog.mapSize=Elekti grandecon de mapo modifierFormat.unknown=??? monarchDialog.default=Mesaĝo de la Krono diff --git a/data/strings/FreeColMessages_es_ES.properties b/data/strings/FreeColMessages_es_ES.properties index c65926c38c..026cc9c188 100644 --- a/data/strings/FreeColMessages_es_ES.properties +++ b/data/strings/FreeColMessages_es_ES.properties @@ -2902,11 +2902,6 @@ mapEditorTransformPanel.minorRiver=Arroyo mapEditorTransformPanel.changeRiverConnections=Añadir/quitar conexiones de ríos mapEditorTransformPanel.setRiverStyle=Establecer el estilo de río mapEditorTransformPanel.resource=Cambiar/eliminar recurso -freecol.map.Africa=África -freecol.map.America_large=América (grande) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Cuenca del Caribe -freecol.map.South_America=América del Sur mapSizeDialog.mapSize=Seleccionar tamaño de mapa modifierFormat.unknown=??? monarchDialog.default=Un mensaje de la Corona diff --git a/data/strings/FreeColMessages_eu.properties b/data/strings/FreeColMessages_eu.properties index 507b70fb19..90fe9dcb02 100644 --- a/data/strings/FreeColMessages_eu.properties +++ b/data/strings/FreeColMessages_eu.properties @@ -928,10 +928,6 @@ loadingSavegameDialog.privateMultiplayer=Multijokolari pribatua loadingSavegameDialog.publicMultiplayer=Multijokolari publikoa loadingSavegameDialog.singlePlayer=Jokalari bakarra loadingSavegameDialog.name=Gordetako partida kargatzen -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (handia) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Karibea mapSizeDialog.mapSize=Maparen tamaina aukeratu monarchDialog.default=Koroaren mezua newPanel.getServerList=Lortu zerbitzarien zerrenda diff --git a/data/strings/FreeColMessages_fi.properties b/data/strings/FreeColMessages_fi.properties index 1aa44f6e5c..8216a74c47 100644 --- a/data/strings/FreeColMessages_fi.properties +++ b/data/strings/FreeColMessages_fi.properties @@ -1970,12 +1970,6 @@ loadingSavegameDialog.name=Ladataan tallennettua peliä mapEditorTransformPanel.majorRiver=Suurjoki mapEditorTransformPanel.minorRiver=Sivujoki mapEditorTransformPanel.resource=Luonnonvara -freecol.map.Africa=Afrikka -freecol.map.America_large=Amerikka (suuri) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Karibian valuma-alue -freecol.map.Caribbean_large=Karibia (suuri) -freecol.map.South_America=Etelä-Amerikka mapSizeDialog.mapSize=Valitse kartan koko monarchDialog.default=Viesti Kruunulta newPanel.editDifficulty=Muokkaa vaikeutta diff --git a/data/strings/FreeColMessages_fr.properties b/data/strings/FreeColMessages_fr.properties index 8a845e4952..62402f8e1e 100644 --- a/data/strings/FreeColMessages_fr.properties +++ b/data/strings/FreeColMessages_fr.properties @@ -3023,12 +3023,6 @@ mapEditorTransformPanel.minorRiver=Ruisseau mapEditorTransformPanel.changeRiverConnections=Ajouter/supprimer des connexions de rivières mapEditorTransformPanel.setRiverStyle=Définir le style de rivière mapEditorTransformPanel.resource=Modifier/supprimer des ressources -freecol.map.Africa=Afrique -freecol.map.America_large=Amérique (grande) -freecol.map.Australia=Australie -freecol.map.Caribbean_basin=Bassin des Caraïbes -freecol.map.Caribbean_large=les Caraïbes (grand) -freecol.map.South_America=Amérique du Sud mapGeneratorOptionsDialog.badWidth=La largeur de la carte (%width%) est trop petite, inférieure à quatre fois la distance au bord (%edge%) mapSizeDialog.mapSize=Sélectionner la taille de la carte modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_gl.properties b/data/strings/FreeColMessages_gl.properties index f4c43f432a..e20e867577 100644 --- a/data/strings/FreeColMessages_gl.properties +++ b/data/strings/FreeColMessages_gl.properties @@ -2536,10 +2536,6 @@ mapEditorTransformPanel.chooseResource=Escolle un recurso mapEditorTransformPanel.majorRiver=Río importante mapEditorTransformPanel.minorRiver=Río pequeno mapEditorTransformPanel.resource=Cambiar/eliminar o recurso -freecol.map.Africa=África -freecol.map.America_large=América (grande) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Conca do Caribe mapSizeDialog.mapSize=Selecciona o tamaño do mapa newPanel.editDifficulty=Modificar a dificultade newPanel.getServerList=Obter a lista de servidores diff --git a/data/strings/FreeColMessages_he.properties b/data/strings/FreeColMessages_he.properties index c1d4f540da..42db5774ae 100644 --- a/data/strings/FreeColMessages_he.properties +++ b/data/strings/FreeColMessages_he.properties @@ -1340,8 +1340,6 @@ loadingSavegameDialog.name=טעינת משחק שמור mapEditorTransformPanel.majorRiver=נחל גדול mapEditorTransformPanel.minorRiver=נחל קטן mapEditorTransformPanel.resource=שינוי/הסרת משאב -freecol.map.Africa=אפריקה -freecol.map.Australia=אוסטרליה mapSizeDialog.mapSize=בחר גודל מפה newPanel.getServerList=אחזר את רשימת השרתים newPanel.joinMultiPlayerGame=הצטרפו למשחק מרובה שחקנים diff --git a/data/strings/FreeColMessages_hsb.properties b/data/strings/FreeColMessages_hsb.properties index 5c9d56e013..4adeb9ddb2 100644 --- a/data/strings/FreeColMessages_hsb.properties +++ b/data/strings/FreeColMessages_hsb.properties @@ -1561,10 +1561,6 @@ mapEditorTransformPanel.chooseResource=žurło wuzwolić mapEditorTransformPanel.majorRiver=Wulkorěka mapEditorTransformPanel.minorRiver=Rěčka mapEditorTransformPanel.resource=Resursu změnić/wotstronić -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (wulka) -freecol.map.Australia=Awstralija -freecol.map.Caribbean_basin=Karibiski basenk mapSizeDialog.mapSize=Wulkosć karty wubrać newPanel.getServerList=Lisćinu serwerow wotwołać newPanel.joinMultiPlayerGame=Na hrě z wjcorymi hrajerjemi so wobdźělić diff --git a/data/strings/FreeColMessages_hu.properties b/data/strings/FreeColMessages_hu.properties index ef18f29fa8..411c3cc3fc 100644 --- a/data/strings/FreeColMessages_hu.properties +++ b/data/strings/FreeColMessages_hu.properties @@ -2489,10 +2489,6 @@ loadingSavegameDialog.name=Mentett állás betöltése... mapEditorTransformPanel.majorRiver=Folyam mapEditorTransformPanel.minorRiver=Apró folyó mapEditorTransformPanel.resource=Erőforrás változtatása/eltávolítása -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (nagy) -freecol.map.Australia=Ausztrália -freecol.map.Caribbean_basin=Karib-tengeri medence mapSizeDialog.mapSize=Térképméret választása nativeDemandDialog.name=A bennszülöttek sarcot követelnek %colony% településen newPanel.editDifficulty=Nehézség szerkesztése diff --git a/data/strings/FreeColMessages_ia.properties b/data/strings/FreeColMessages_ia.properties index 99e39c1a21..7a1ba3260c 100644 --- a/data/strings/FreeColMessages_ia.properties +++ b/data/strings/FreeColMessages_ia.properties @@ -2774,10 +2774,6 @@ mapEditorTransformPanel.chooseResource=Selige un ressource mapEditorTransformPanel.majorRiver=Fluvio major mapEditorTransformPanel.minorRiver=Fluvio minor mapEditorTransformPanel.resource=Modificar/remover ressource -freecol.map.Africa=Africa -freecol.map.America_large=America (grande) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Mar Caribe mapSizeDialog.mapSize=Selige le dimension del carta monarchDialog.default=Un message del Corona newPanel.editDifficulty=Modificar difficultate diff --git a/data/strings/FreeColMessages_it_IT.properties b/data/strings/FreeColMessages_it_IT.properties index 8eaba6032b..447fe95a44 100644 --- a/data/strings/FreeColMessages_it_IT.properties +++ b/data/strings/FreeColMessages_it_IT.properties @@ -2801,11 +2801,6 @@ mapEditorTransformPanel.chooseResource=Scegli risorsa mapEditorTransformPanel.majorRiver=Fiume mapEditorTransformPanel.minorRiver=Affluente mapEditorTransformPanel.resource=Cambia/Rimuovi Risorsa -freecol.map.Africa=Africa -freecol.map.America_large=America (grande) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Bacino dei Caraibi -freecol.map.South_America=Sud America mapSizeDialog.mapSize=Scegli la dimensione della mappa modifierFormat.unknown=??? monarchDialog.default=Messaggio dalla Corona diff --git a/data/strings/FreeColMessages_ja.properties b/data/strings/FreeColMessages_ja.properties index 49683f746d..cfb2281118 100644 --- a/data/strings/FreeColMessages_ja.properties +++ b/data/strings/FreeColMessages_ja.properties @@ -2161,11 +2161,6 @@ loadingSavegameDialog.name=保存されたゲームの読み込み mapEditorTransformPanel.majorRiver=大きな河川 mapEditorTransformPanel.minorRiver=小さな河川 mapEditorTransformPanel.resource=資源の変更・削除 -freecol.map.Africa=アフリカ -freecol.map.America_large=アメリカ (大) -freecol.map.Australia=オーストラリア -freecol.map.Caribbean_basin=カリブ海地域 -freecol.map.South_America=南米 mapSizeDialog.mapSize=マップの大きさを選ぶ monarchDialog.default=国王からのメッセージ newPanel.editDifficulty=難易度を編集 diff --git a/data/strings/FreeColMessages_ko.properties b/data/strings/FreeColMessages_ko.properties index e5c5fe491b..e4b0f3a3d7 100644 --- a/data/strings/FreeColMessages_ko.properties +++ b/data/strings/FreeColMessages_ko.properties @@ -1382,11 +1382,6 @@ loadingSavegameDialog.name=저장 게임 불러오기 mapEditorTransformPanel.majorRiver=강 본류 mapEditorTransformPanel.minorRiver=강 지류 mapEditorTransformPanel.resource=자원 변경/제거 -freecol.map.Africa=아프리카 -freecol.map.America_large=아메리카 (큼) -freecol.map.Australia=호주 -freecol.map.Caribbean_basin=카리브해 웅덩이 -freecol.map.South_America=남아메리카 mapSizeDialog.mapSize=지도 크기 선택 monarchDialog.default=Crown이 보낸 메시지 newPanel.editDifficulty=난이도 편집 diff --git a/data/strings/FreeColMessages_lt.properties b/data/strings/FreeColMessages_lt.properties index 179e646465..5cf2197275 100644 --- a/data/strings/FreeColMessages_lt.properties +++ b/data/strings/FreeColMessages_lt.properties @@ -2796,10 +2796,6 @@ mapEditorTransformPanel.chooseResource=Pasirinkti išteklį mapEditorTransformPanel.majorRiver=Didžioji upė mapEditorTransformPanel.minorRiver=Mažoji upė mapEditorTransformPanel.resource=Keisti/šalinti išteklius -freecol.map.Africa=Afrika -freecol.map.America_large=Amerikos (didelis) -freecol.map.Australia=Australija -freecol.map.Caribbean_basin=Karibų baseinas mapSizeDialog.mapSize=Pasirinkite žemėlapio dydį monarchDialog.default=Pranešimas iš Karūnos newPanel.editDifficulty=Keisti sunkumą diff --git a/data/strings/FreeColMessages_mk.properties b/data/strings/FreeColMessages_mk.properties index 82613441b0..d9ed5f4513 100644 --- a/data/strings/FreeColMessages_mk.properties +++ b/data/strings/FreeColMessages_mk.properties @@ -2967,10 +2967,6 @@ mapEditorTransformPanel.chooseResource=Изберете ресурс mapEditorTransformPanel.majorRiver=Голема река mapEditorTransformPanel.minorRiver=Мала река mapEditorTransformPanel.resource=Промени/отстрани ресурс -freecol.map.Africa=Африка -freecol.map.America_large=Америка (голема) -freecol.map.Australia=Австралија -freecol.map.Caribbean_basin=Карипски Бразил mapSizeDialog.mapSize=Одберете големина на картата modifierFormat.unknown=??? monarchDialog.default=Порака од Круната diff --git a/data/strings/FreeColMessages_ms.properties b/data/strings/FreeColMessages_ms.properties index 29ec8e2828..e6ea8f55a2 100644 --- a/data/strings/FreeColMessages_ms.properties +++ b/data/strings/FreeColMessages_ms.properties @@ -2695,10 +2695,6 @@ mapEditorTransformPanel.chooseResource=Pilih sumber mapEditorTransformPanel.majorRiver=Sungai utama mapEditorTransformPanel.minorRiver=Sungai kecil mapEditorTransformPanel.resource=Tukar/gugurkan sumber -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (besar) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Lembangan Caribbean mapSizeDialog.mapSize=Pilih saiz peta modifierFormat.unknown=??? monarchDialog.default=Utusan dari Kerajaan diff --git a/data/strings/FreeColMessages_nb_NO.properties b/data/strings/FreeColMessages_nb_NO.properties index 7b4a42e3de..277a31416d 100644 --- a/data/strings/FreeColMessages_nb_NO.properties +++ b/data/strings/FreeColMessages_nb_NO.properties @@ -1060,10 +1060,6 @@ loadingSavegameDialog.name=Laster lagret spill mapEditorTransformPanel.majorRiver=Stor elv mapEditorTransformPanel.minorRiver=Liten elv mapEditorTransformPanel.resource=Endre/fjern ressurs -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (stort) -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Karibiske hav mapSizeDialog.mapSize=Velg kartstørrelse monarchDialog.default=En melding fra Kronen newPanel.getServerList=Hent tjenerliste diff --git a/data/strings/FreeColMessages_nds.properties b/data/strings/FreeColMessages_nds.properties index df5f2ad1f5..3966407f43 100644 --- a/data/strings/FreeColMessages_nds.properties +++ b/data/strings/FreeColMessages_nds.properties @@ -1170,9 +1170,6 @@ loadingSavegameDialog.publicMultiplayer=Mehrspeler apen loadingSavegameDialog.name=Speelstand warrt laadt mapEditorTransformPanel.majorRiver=Groot Stroom mapEditorTransformPanel.minorRiver=Lütt Stroom -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (groot) -freecol.map.Australia=Australien newPanel.getServerList=Serverlist kriegen newPanel.joinMultiPlayerGame=bi Mehrspelerspeel mitmaken newPanel.publicServer=Apen Server diff --git a/data/strings/FreeColMessages_nl.properties b/data/strings/FreeColMessages_nl.properties index b4355d0c92..19c27880ad 100644 --- a/data/strings/FreeColMessages_nl.properties +++ b/data/strings/FreeColMessages_nl.properties @@ -3058,12 +3058,6 @@ mapEditorTransformPanel.chooseResource=Kies een hulpbron mapEditorTransformPanel.majorRiver=Grote rivier mapEditorTransformPanel.minorRiver=Kleine rivier mapEditorTransformPanel.resource=Middelen wijzigen/verwijderen -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (groot) -freecol.map.Australia=Australië -freecol.map.Caribbean_basin=Caribisch gebied -freecol.map.Caribbean_large=Caribbisch (groot) -freecol.map.South_America=Zuid-Amerika mapGeneratorOptionsDialog.badWidth=De kaart is te smal (%width%), minder dan vier keer de randafstand (%edge%) mapSizeDialog.mapSize=Selecteer kaartgrootte modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_nl_BE.properties b/data/strings/FreeColMessages_nl_BE.properties index b6fb7d66bc..5c77509f58 100644 --- a/data/strings/FreeColMessages_nl_BE.properties +++ b/data/strings/FreeColMessages_nl_BE.properties @@ -1829,10 +1829,6 @@ loadingSavegameDialog.name=Spel wordt geladen mapEditorTransformPanel.majorRiver=Grote rivier mapEditorTransformPanel.minorRiver=Kleine rivier mapEditorTransformPanel.resource=Hulpmiddel wijzigen/verwijderen -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika(Groot) -freecol.map.Australia=Australië -freecol.map.Caribbean_basin=Golf van Carabië mapSizeDialog.mapSize=Kies de grootte van de kaart newPanel.editDifficulty=Verander moeilijkheidsgraad newPanel.getServerList=Serverlijst ophalen diff --git a/data/strings/FreeColMessages_oc.properties b/data/strings/FreeColMessages_oc.properties index 08b0e048e6..21deb17700 100644 --- a/data/strings/FreeColMessages_oc.properties +++ b/data/strings/FreeColMessages_oc.properties @@ -2717,11 +2717,6 @@ mapEditorTransformPanel.minorRiver=Riuet mapEditorTransformPanel.changeRiverConnections=Apondre/suprimir de connexions de ribièras mapEditorTransformPanel.setRiverStyle=Definir l'estil de ribièra mapEditorTransformPanel.resource=Modificar/suprimir de ressorsas -freecol.map.Africa=Africa -freecol.map.America_large=America (granda) -freecol.map.Australia=Austràlia -freecol.map.Caribbean_basin=Bacin de las Caribas -freecol.map.Caribbean_large=las Caribas (grand) mapSizeDialog.mapSize=Seleccionar la talha de la mapa modifierFormat.unknown=??? monarchDialog.default=Un messatge de la Corona diff --git a/data/strings/FreeColMessages_pl_PL.properties b/data/strings/FreeColMessages_pl_PL.properties index 525eade419..ddad8d0de2 100644 --- a/data/strings/FreeColMessages_pl_PL.properties +++ b/data/strings/FreeColMessages_pl_PL.properties @@ -2938,11 +2938,6 @@ mapEditorTransformPanel.minorRiver=Mała rzeka mapEditorTransformPanel.changeRiverConnections=Dodaj/usuń połączenia rzek mapEditorTransformPanel.setRiverStyle=Ustaw styl rzek mapEditorTransformPanel.resource=Zmień lub usuń surowce -freecol.map.Africa=Afryka -freecol.map.America_large=Ameryka Pn. i Pd. -freecol.map.Australia=Australia -freecol.map.Caribbean_basin=Karaiby -freecol.map.South_America=Ameryka Południowa mapSizeDialog.mapSize=Wybież rozmiar mapy monarchDialog.default=Wiadomość od Korony newPanel.editDifficulty=Edytuj stopień trudności diff --git a/data/strings/FreeColMessages_pt_BR.properties b/data/strings/FreeColMessages_pt_BR.properties index 7dc8643259..6f15f90331 100644 --- a/data/strings/FreeColMessages_pt_BR.properties +++ b/data/strings/FreeColMessages_pt_BR.properties @@ -3001,12 +3001,6 @@ mapEditorTransformPanel.minorRiver=Rio secundário mapEditorTransformPanel.changeRiverConnections=Adicionar/remover conexões do rio mapEditorTransformPanel.setRiverStyle=Definir estilo de rio mapEditorTransformPanel.resource=Alterar/Remover recurso -freecol.map.Africa=África -freecol.map.America_large=América (grande) -freecol.map.Australia=Austrália -freecol.map.Caribbean_basin=Bacia do Caribe -freecol.map.Caribbean_large=Caribe (grande) -freecol.map.South_America=América do Sul mapGeneratorOptionsDialog.badWidth=A largura do mapa (%width%) é demasiado pequena, inferior a quatro vezes a distância até a margem (%edge%) mapSizeDialog.mapSize=Selecionar o tamanho do mapa modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_pt_PT.properties b/data/strings/FreeColMessages_pt_PT.properties index b571dd87bc..a3a2909923 100644 --- a/data/strings/FreeColMessages_pt_PT.properties +++ b/data/strings/FreeColMessages_pt_PT.properties @@ -3042,12 +3042,6 @@ mapEditorTransformPanel.minorRiver=Rio secundário mapEditorTransformPanel.changeRiverConnections=Adicionar ou remover ligações ao rio mapEditorTransformPanel.setRiverStyle=Definir estilo do rio mapEditorTransformPanel.resource=Alterar ou remover recurso -freecol.map.Africa=África -freecol.map.America_large=América (grande) -freecol.map.Australia=Austrália -freecol.map.Caribbean_basin=Bacia das Caraíbas -freecol.map.Caribbean_large=Caraíbas (grande) -freecol.map.South_America=América do Sul mapGeneratorOptionsDialog.badWidth=A largura do mapa (%width%) é demasiado pequena, inferior a quatro vezes a distância até a margem (%edge%) mapSizeDialog.mapSize=Escolha o tamanho do mapa modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_qqq.properties b/data/strings/FreeColMessages_qqq.properties index 37e4dc8ad7..97ecceceae 100644 --- a/data/strings/FreeColMessages_qqq.properties +++ b/data/strings/FreeColMessages_qqq.properties @@ -661,8 +661,6 @@ freeColProgressBar.turnsToComplete={{Identical|Turn}} infoPanel.moves=See http://www.freecol.org/images/screen-0.8.0-large.jpg\n{{Identical|Move}} informationPanel.display={{Identical|Display}} loadingSavegameDialog.port={{Identical|Port}} -freecol.map.Africa={{Identical|Africa}} -freecol.map.Australia={{Identical|Australia}} modifierFormat.unknown={{optional}} newPanel.editDifficulty=Used as label for button.\n\nSee also:\n* {{msg-freecol|ShowDifficulty}} newPanel.getServerList=获取服务器列表 diff --git a/data/strings/FreeColMessages_ru.properties b/data/strings/FreeColMessages_ru.properties index 91359da4e8..3e5874ae27 100644 --- a/data/strings/FreeColMessages_ru.properties +++ b/data/strings/FreeColMessages_ru.properties @@ -3015,11 +3015,6 @@ mapEditorTransformPanel.chooseResource=Выберите ресурс mapEditorTransformPanel.majorRiver=Широкая река mapEditorTransformPanel.minorRiver=Узкая река mapEditorTransformPanel.resource=Изменить/удалить ресурс -freecol.map.Africa=Африка -freecol.map.America_large=Америка (большая) -freecol.map.Australia=Австралия -freecol.map.Caribbean_basin=Карибский бассейн -freecol.map.South_America=Южная Америка mapSizeDialog.mapSize=Выберите размер карты modifierFormat.unknown=??? monarchDialog.default=Послание от Короны diff --git a/data/strings/FreeColMessages_sk.properties b/data/strings/FreeColMessages_sk.properties index dd17aba970..c1804999c3 100644 --- a/data/strings/FreeColMessages_sk.properties +++ b/data/strings/FreeColMessages_sk.properties @@ -2901,12 +2901,6 @@ mapEditorTransformPanel.minorRiver=Menšia rieka mapEditorTransformPanel.changeRiverConnections=Pridať/odstrániť pripojenia riek mapEditorTransformPanel.setRiverStyle=Nastaviť štýl rieky mapEditorTransformPanel.resource=Zmeniť/presunúť zdroj -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (veľká) -freecol.map.Australia=Austrália -freecol.map.Caribbean_basin=Karibská oblasť -freecol.map.Caribbean_large=Karibik (veľký) -freecol.map.South_America=Južná Amerika mapGeneratorOptionsDialog.badWidth=Šírka mapy (%width%) je príliš úzka, menej než štyrikrát než vzdialenosť od okraju (%edge%) mapSizeDialog.mapSize=Zvoliť veľkosť mapy modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_sr-ec.properties b/data/strings/FreeColMessages_sr-ec.properties index bad98c4a80..4a29b6c675 100644 --- a/data/strings/FreeColMessages_sr-ec.properties +++ b/data/strings/FreeColMessages_sr-ec.properties @@ -1163,11 +1163,6 @@ loadingSavegameDialog.name=Учитавам сачувану игру... mapEditorTransformPanel.majorRiver=Већа река mapEditorTransformPanel.minorRiver=Мања река mapEditorTransformPanel.resource=Промени/уклони ресурс -freecol.map.Africa=Африка -freecol.map.America_large=Америка (велика) -freecol.map.Australia=Аустралија -freecol.map.Caribbean_basin=Карипски басен -freecol.map.Caribbean_large=Кариби (велики) mapSizeDialog.mapSize=Изаберите величину мапе modifierFormat.unknown=??? monarchDialog.default=Порука са престола diff --git a/data/strings/FreeColMessages_sv_SE.properties b/data/strings/FreeColMessages_sv_SE.properties index fe57716602..69ab177d58 100644 --- a/data/strings/FreeColMessages_sv_SE.properties +++ b/data/strings/FreeColMessages_sv_SE.properties @@ -2640,11 +2640,6 @@ mapEditorTransformPanel.chooseResource=Välj resurs mapEditorTransformPanel.majorRiver=Större flod mapEditorTransformPanel.minorRiver=Mindre flod mapEditorTransformPanel.resource=Byt ut/avlägsna naturtillgång -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (stor) -freecol.map.Australia=Australien -freecol.map.Caribbean_basin=Karibiska havet -freecol.map.South_America=Sydamerika mapGeneratorOptionsDialog.badWidth=Kartans bredd (%width%) är för smal, mindre än 4 gånger avståndet mellan kanterna (%edge%) mapSizeDialog.mapSize=Välj kartstorlek modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_tr.properties b/data/strings/FreeColMessages_tr.properties index d72e70cd70..afa20d66a2 100644 --- a/data/strings/FreeColMessages_tr.properties +++ b/data/strings/FreeColMessages_tr.properties @@ -2948,12 +2948,6 @@ mapEditorTransformPanel.minorRiver=Küçük nehir mapEditorTransformPanel.changeRiverConnections=Nehir bağlantıları ekle/kaldır mapEditorTransformPanel.setRiverStyle=Nehir stilini ayarla mapEditorTransformPanel.resource=Kaynağı değiştir/çıkar -freecol.map.Africa=Afrika -freecol.map.America_large=Amerika (büyük) -freecol.map.Australia=Avustralya -freecol.map.Caribbean_basin=Karayip Havzası -freecol.map.Caribbean_large=Karayipler (büyük) -freecol.map.South_America=Güney Amerika mapGeneratorOptionsDialog.badWidth=Harita genişliği (%width%) çok dar, kenar mesafesinin 4 katından az (%edge%) mapSizeDialog.mapSize=Harita boyutu seç modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_uk.properties b/data/strings/FreeColMessages_uk.properties index 2d89caaf6f..d0324b1437 100644 --- a/data/strings/FreeColMessages_uk.properties +++ b/data/strings/FreeColMessages_uk.properties @@ -3031,12 +3031,6 @@ mapEditorTransformPanel.minorRiver=Мала річка mapEditorTransformPanel.changeRiverConnections=Додати/вилучити з'єднання річок mapEditorTransformPanel.setRiverStyle=Встановити стиль річок mapEditorTransformPanel.resource=Змінити/вилучити ресурс -freecol.map.Africa=Африка -freecol.map.America_large=Америка (велика) -freecol.map.Australia=Австралія -freecol.map.Caribbean_basin=Карибський басейн -freecol.map.Caribbean_large=Кариби (велика) -freecol.map.South_America=Південна Америка mapGeneratorOptionsDialog.badWidth=Ширина мапи (%width%) є надто малою, менш як у 4 рази від відстані між краями (%edge%) mapSizeDialog.mapSize=Виберіть розмір мапи modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_zh-hant.properties b/data/strings/FreeColMessages_zh-hant.properties index 3e1354c32d..e52eb8faff 100644 --- a/data/strings/FreeColMessages_zh-hant.properties +++ b/data/strings/FreeColMessages_zh-hant.properties @@ -2971,12 +2971,6 @@ mapEditorTransformPanel.minorRiver=小河 mapEditorTransformPanel.changeRiverConnections=添加/移除河流連結 mapEditorTransformPanel.setRiverStyle=設定河流樣式 mapEditorTransformPanel.resource=修改/刪除資源 -freecol.map.Africa=非洲 -freecol.map.America_large=美洲 (大) -freecol.map.Australia=澳洲 -freecol.map.Caribbean_basin=加勒比海盆地 -freecol.map.Caribbean_large=加勒比(大) -freecol.map.South_America=南美洲 mapGeneratorOptionsDialog.badWidth=地圖寬度(%width%)太狹窄了:它小於邊緣距離的四倍(%edge%) mapSizeDialog.mapSize=選擇地圖大小 modifierFormat.unknown=??? diff --git a/data/strings/FreeColMessages_zh_CN.properties b/data/strings/FreeColMessages_zh_CN.properties index 35ea95a957..7a99a1b19d 100644 --- a/data/strings/FreeColMessages_zh_CN.properties +++ b/data/strings/FreeColMessages_zh_CN.properties @@ -3040,12 +3040,6 @@ mapEditorTransformPanel.minorRiver=小河 mapEditorTransformPanel.changeRiverConnections=添加/移除河流连接 mapEditorTransformPanel.setRiverStyle=设置河流样式 mapEditorTransformPanel.resource=修改/移除资源 -freecol.map.Africa=非洲 -freecol.map.America_large=美国(大) -freecol.map.Australia=澳大利亚 -freecol.map.Caribbean_basin=加勒比海盆地 -freecol.map.Caribbean_large=加勒比(大) -freecol.map.South_America=南美洲 mapGeneratorOptionsDialog.badWidth=地图宽度(%width%)太窄了,它要小于边缘(%edge%)的四倍距离 mapSizeDialog.mapSize=选择地图大小 modifierFormat.unknown=??? diff --git a/src/net/sf/freecol/client/gui/Canvas.java b/src/net/sf/freecol/client/gui/Canvas.java index c4f69f6443..9272f7876a 100644 --- a/src/net/sf/freecol/client/gui/Canvas.java +++ b/src/net/sf/freecol/client/gui/Canvas.java @@ -28,23 +28,25 @@ import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.Image; +import java.awt.MouseInfo; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; -import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JDesktopPane; import javax.swing.JInternalFrame; @@ -53,199 +55,65 @@ import javax.swing.JMenuItem; import javax.swing.SwingUtilities; import javax.swing.UIManager; +import javax.swing.Timer; import javax.swing.border.EmptyBorder; -import javax.swing.filechooser.FileFilter; import javax.swing.plaf.basic.BasicInternalFrameUI; import net.sf.freecol.FreeCol; import net.sf.freecol.client.ClientOptions; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.action.FreeColAction; -import net.sf.freecol.client.gui.panel.AboutPanel; -import net.sf.freecol.client.gui.panel.BuildQueuePanel; -import net.sf.freecol.client.gui.dialog.CaptureGoodsDialog; -import net.sf.freecol.client.gui.panel.ChatPanel; -import net.sf.freecol.client.gui.dialog.ChooseFoundingFatherDialog; -import net.sf.freecol.client.gui.dialog.ClientOptionsDialog; -import net.sf.freecol.client.gui.panel.ColonyPanel; -import net.sf.freecol.client.gui.panel.colopedia.ColopediaPanel; -import net.sf.freecol.client.gui.panel.ColorChooserPanel; -import net.sf.freecol.client.gui.panel.report.CompactLabourReport; -import net.sf.freecol.client.gui.dialog.ConfirmDeclarationDialog; -import net.sf.freecol.client.gui.panel.DeclarationPanel; -import net.sf.freecol.client.gui.dialog.DifficultyDialog; -import net.sf.freecol.client.gui.dialog.DumpCargoDialog; -import net.sf.freecol.client.gui.dialog.EditOptionDialog; -import net.sf.freecol.client.gui.dialog.EditSettlementDialog; -import net.sf.freecol.client.gui.dialog.EmigrationDialog; -import net.sf.freecol.client.gui.dialog.EndTurnDialog; -import net.sf.freecol.client.gui.panel.ErrorPanel; -import net.sf.freecol.client.gui.panel.EuropePanel; -import net.sf.freecol.client.gui.panel.EventPanel; -import net.sf.freecol.client.gui.panel.FindSettlementPanel; -import net.sf.freecol.client.gui.dialog.FirstContactDialog; -import net.sf.freecol.client.gui.dialog.FreeColChoiceDialog; -import net.sf.freecol.client.gui.dialog.FreeColConfirmDialog; import net.sf.freecol.client.gui.dialog.FreeColDialog; -import net.sf.freecol.client.gui.panel.FreeColPanel; -import net.sf.freecol.client.gui.dialog.FreeColStringInputDialog; -import net.sf.freecol.client.gui.dialog.GameOptionsDialog; -import net.sf.freecol.client.gui.panel.IndianSettlementPanel; -import net.sf.freecol.client.gui.panel.InformationPanel; -import net.sf.freecol.client.gui.panel.report.LabourData.UnitData; -import net.sf.freecol.client.gui.dialog.LoadDialog; -import net.sf.freecol.client.gui.dialog.LoadingSavegameDialog; -import net.sf.freecol.client.gui.panel.MainPanel; -import net.sf.freecol.client.gui.panel.MapEditorTransformPanel; -import net.sf.freecol.client.gui.dialog.MapGeneratorOptionsDialog; -import net.sf.freecol.client.gui.dialog.MapSizeDialog; -import net.sf.freecol.client.gui.dialog.MonarchDialog; -import net.sf.freecol.client.gui.dialog.NativeDemandDialog; -import net.sf.freecol.client.gui.dialog.NegotiationDialog; -import net.sf.freecol.client.gui.panel.NewPanel; -import net.sf.freecol.client.gui.dialog.Parameters; -import net.sf.freecol.client.gui.dialog.ParametersDialog; -import net.sf.freecol.client.gui.dialog.PreCombatDialog; -import net.sf.freecol.client.gui.panel.PurchasePanel; -import net.sf.freecol.client.gui.panel.RecruitPanel; -import net.sf.freecol.client.gui.panel.report.ReportCargoPanel; -import net.sf.freecol.client.gui.panel.report.ReportClassicColonyPanel; -import net.sf.freecol.client.gui.panel.report.ReportCompactColonyPanel; -import net.sf.freecol.client.gui.panel.report.ReportContinentalCongressPanel; -import net.sf.freecol.client.gui.panel.report.ReportEducationPanel; -import net.sf.freecol.client.gui.panel.report.ReportExplorationPanel; -import net.sf.freecol.client.gui.panel.report.ReportForeignAffairPanel; -import net.sf.freecol.client.gui.panel.report.ReportHighScoresPanel; -import net.sf.freecol.client.gui.panel.report.ReportHistoryPanel; -import net.sf.freecol.client.gui.panel.report.ReportIndianPanel; -import net.sf.freecol.client.gui.panel.report.ReportLabourDetailPanel; -import net.sf.freecol.client.gui.panel.report.ReportLabourPanel; -import net.sf.freecol.client.gui.panel.report.ReportMilitaryPanel; -import net.sf.freecol.client.gui.panel.report.ReportNavalPanel; -import net.sf.freecol.client.gui.panel.report.ReportPanel; -import net.sf.freecol.client.gui.panel.report.ReportProductionPanel; -import net.sf.freecol.client.gui.panel.report.ReportReligiousPanel; -import net.sf.freecol.client.gui.panel.report.ReportRequirementsPanel; -import net.sf.freecol.client.gui.panel.report.ReportTradePanel; -import net.sf.freecol.client.gui.panel.report.ReportTurnPanel; -import net.sf.freecol.client.gui.dialog.RiverStyleDialog; -import net.sf.freecol.client.gui.dialog.SaveDialog; -import net.sf.freecol.client.gui.dialog.ScaleMapSizeDialog; -import net.sf.freecol.client.gui.dialog.SelectAmountDialog; -import net.sf.freecol.client.gui.dialog.SelectDestinationDialog; -import net.sf.freecol.client.gui.dialog.SelectTributeAmountDialog; -import net.sf.freecol.client.gui.panel.ServerListPanel; -import net.sf.freecol.client.gui.panel.StartGamePanel; -import net.sf.freecol.client.gui.panel.StatisticsPanel; -import net.sf.freecol.client.gui.panel.StatusPanel; -import net.sf.freecol.client.gui.panel.TilePanel; -import net.sf.freecol.client.gui.panel.TradeRouteInputPanel; -import net.sf.freecol.client.gui.panel.TradeRoutePanel; -import net.sf.freecol.client.gui.panel.TrainPanel; +import net.sf.freecol.client.gui.menu.InGameMenuBar; +import net.sf.freecol.client.gui.menu.MapEditorMenuBar; +import net.sf.freecol.client.gui.menu.MenuMouseMotionListener; +import net.sf.freecol.client.gui.panel.MapControls; import net.sf.freecol.client.gui.panel.Utility; -import net.sf.freecol.client.gui.dialog.VictoryDialog; -import net.sf.freecol.client.gui.dialog.WarehouseDialog; -import net.sf.freecol.client.gui.panel.WorkProductionPanel; +import net.sf.freecol.client.gui.video.VideoComponent; +import net.sf.freecol.client.gui.video.VideoListener; + import net.sf.freecol.common.i18n.Messages; -import net.sf.freecol.common.io.FreeColDataFile; import net.sf.freecol.common.metaserver.ServerInfo; import net.sf.freecol.common.model.Colony; -import net.sf.freecol.common.model.DiplomaticTrade; import net.sf.freecol.common.model.Direction; -import net.sf.freecol.common.model.FoundingFather; -import net.sf.freecol.common.model.FreeColGameObject; -import net.sf.freecol.common.model.FreeColObject; -import net.sf.freecol.common.model.Game; -import net.sf.freecol.common.model.Goods; -import net.sf.freecol.common.model.GoodsType; -import net.sf.freecol.common.model.HighScore; -import net.sf.freecol.common.model.IndianSettlement; -import net.sf.freecol.common.model.Location; -import net.sf.freecol.common.model.ModelMessage; -import net.sf.freecol.common.model.Monarch.MonarchAction; import net.sf.freecol.common.model.PathNode; -import net.sf.freecol.common.model.Player; -import net.sf.freecol.common.model.Settlement; import net.sf.freecol.common.model.Specification; -import net.sf.freecol.common.model.StringTemplate; import net.sf.freecol.common.model.Tile; import net.sf.freecol.common.model.TradeRoute; -import net.sf.freecol.common.model.TypeCountMap; import net.sf.freecol.common.model.Unit; -import net.sf.freecol.common.model.UnitType; import net.sf.freecol.common.option.IntegerOption; import net.sf.freecol.common.option.Option; import net.sf.freecol.common.option.OptionGroup; +import net.sf.freecol.common.resources.Video; import static net.sf.freecol.common.util.CollectionUtils.*; +import net.sf.freecol.common.util.Introspector; import static net.sf.freecol.common.util.StringUtils.*; -import net.sf.freecol.common.util.Utils; + +// Special case panels, TODO: can we move these to Widgets? +import net.sf.freecol.client.gui.panel.ChatPanel; +import net.sf.freecol.client.gui.panel.ColonyPanel; +import net.sf.freecol.client.gui.panel.ErrorPanel; +import net.sf.freecol.client.gui.panel.FreeColPanel; +import net.sf.freecol.client.gui.panel.MainPanel; +import net.sf.freecol.client.gui.panel.MapEditorTransformPanel; +import net.sf.freecol.client.gui.panel.ServerListPanel; +import net.sf.freecol.client.gui.panel.StartGamePanel; +import net.sf.freecol.client.gui.panel.StatisticsPanel; +import net.sf.freecol.client.gui.panel.StatusPanel; +import net.sf.freecol.client.gui.panel.TradeRouteInputPanel; /** - * The main container for the other GUI components in FreeCol. This - * container is where the panels, dialogs and menus are added. In - * addition, this is the component in which the map graphics are - * displayed. - *

- * Displaying panels and a dialogs - *

- * {@code Canvas} contains methods to display various panels and dialogs. - * Most of these methods use {@link net.sf.freecol.common.i18n i18n} to get - * localized text. Dialogs return results, and may be modal or non-modal. + * The main container for the other GUI components in FreeCol. + * This is where lower level graphics coordination occurs. + * Specific panels and dialogs are over in Widgets + * (TODO) with a few exceptions. */ public final class Canvas extends JDesktopPane { private static final Logger logger = Logger.getLogger(Canvas.class.getName()); - /** A wrapper class for non-modal dialogs. */ - private class DialogCallback implements Runnable { - - /** The dialog to show. */ - private final FreeColDialog fcd; - - /** An optional tile to guide the dialog placement. */ - private final Tile tile; - - /** The handler for the dialog response. */ - private final DialogHandler handler; - - - /** - * Constructor. - * - * @param fcd The parent {@code FreeColDialog}. - * @param tile An optional {@code Tile} to display. - * @param handler The {@code DialogHandler} to call when run. - */ - public DialogCallback(FreeColDialog fcd, Tile tile, - DialogHandler handler) { - this.fcd = fcd; - this.tile = tile; - this.handler = handler; - } - - - // Implement Runnable - - @Override - public void run() { - // Display the dialog... - viewFreeColDialog(fcd, tile); - // ...and use another thread to wait for a dialog response... - new Thread(fcd.toString()) { - @Override - public void run() { - while (!fcd.responded()) { - Utils.delay(500, "Dialog interrupted."); - } - // ...before handling the result. - handler.handle(fcd.getResponse()); - } - }.start(); - } - }; - - private static enum PopupPosition { + public static enum PopupPosition { ORIGIN, CENTERED, CENTERED_LEFT, @@ -255,9 +123,6 @@ private static enum PopupPosition { /** Number of tries to find a clear spot on the canvas. */ private static final int MAXTRY = 3; - /** Number of pixels that must be moved before a goto is enabled. */ - private static final int DRAG_THRESHOLD = 16; - /** The cursor to show for goto operations. */ private static final java.awt.Cursor GO_CURSOR = (java.awt.Cursor)UIManager.get("cursor.go"); @@ -268,320 +133,176 @@ private static class ToolBoxFrame extends JInternalFrame {} /** The game client. */ private final FreeColClient freeColClient; - /** The parent GUI. */ - private final GUI gui; - + /** The graphics device to display to. */ private final GraphicsDevice graphicsDevice; - /** The parent frame, either a window or the full screen. */ - private FreeColFrame frame; + /** The image library to create icons etc with. */ + private final ImageLibrary imageLibrary; + /** Is the canvas in windowed mode? */ private boolean windowed; - private MainPanel mainPanel; - - private final StartGamePanel startGamePanel; - - private final StatusPanel statusPanel; - - private final ChatPanel chatPanel; + /** The parent frame, either a window or the full screen. */ + private FreeColFrame parentFrame; - private final ChatDisplay chatDisplay; + /** Remember the current size (from getSize()), check for changes. */ + private Dimension oldSize = null; + /** The component that displays the map. */ private final MapViewer mapViewer; - /** Where the map was drag-clicked. */ - private Point dragPoint = null; + /** The various sorts of map controls. */ + private MapControls mapControls; /** Has a goto operation started? */ private boolean gotoStarted = false; + /** The special overlay used when it is not the player turn. */ private GrayLayer greyLayer; - private final ServerListPanel serverListPanel; - - /** Used to detect resizing. */ - private Dimension oldSize = null; - - private boolean clientOptionsDialogShowing = false; + /** The chat message area. */ + private final ChatDisplay chatDisplay; /** The dialogs in view. */ private final List> dialogs = new ArrayList<>(); + /** Cached panels. TODO: check if we still need these */ + private MainPanel mainPanel; + private final StartGamePanel startGamePanel; + private final StatusPanel statusPanel; + private final ChatPanel chatPanel; + private final ServerListPanel serverListPanel; + /** * The constructor to use. * * @param freeColClient The {@code FreeColClient} for the game. - * @param graphicsDevice The used graphics device. - * @param gui The gui. - * @param desiredSize The desired size of the frame. - * @param mapViewer The object responsible of drawing the map onto - * this component. + * @param graphicsDevice The {@code GraphicsDevice} to display on. + * @param desiredSize The desired size of the parent frame. + * @param mapViewer The object responsible of drawing the map. */ public Canvas(final FreeColClient freeColClient, final GraphicsDevice graphicsDevice, - final GUI gui, final Dimension desiredSize, MapViewer mapViewer) { this.freeColClient = freeColClient; - this.gui = gui; this.graphicsDevice = graphicsDevice; - this.mapViewer = mapViewer; - this.greyLayer = new GrayLayer(freeColClient); + this.imageLibrary = mapViewer.getImageLibrary(); // Determine if windowed mode should be used and set the window size. + this.windowed = checkWindowed(graphicsDevice, desiredSize); Rectangle windowBounds = null; - if (desiredSize == null) { - if(graphicsDevice.isFullScreenSupported()) { - windowed = false; - logger.info("Full screen mode used."); - } else { - windowed = true; - logger.warning("Full screen mode not supported."); - System.err.println(Messages.message("client.fullScreen")); - } - } else { - windowed = true; - if(desiredSize.width > 0 && desiredSize.height > 0) { - windowBounds = new Rectangle(desiredSize); - logger.info("Windowed mode using desired window size of " + desiredSize); - } else { - logger.info("Windowed mode used."); - } + if (this.windowed && desiredSize != null + && desiredSize.width > 0 && desiredSize.height > 0) { + windowBounds = new Rectangle(desiredSize); } + this.parentFrame = createFrame(null, windowBounds); + this.oldSize = getSize(); + this.mapViewer = mapViewer; + this.mapControls = null; + this.greyLayer = new GrayLayer(freeColClient); + this.chatDisplay = new ChatDisplay(); + setDoubleBuffered(true); setOpaque(false); setLayout(null); + setFocusable(true); + setFocusTraversalKeysEnabled(false); + createKeyBindings(); - chatDisplay = new ChatDisplay(); chatPanel = new ChatPanel(freeColClient); serverListPanel = new ServerListPanel(freeColClient, freeColClient.getConnectController()); startGamePanel = new StartGamePanel(freeColClient); statusPanel = new StatusPanel(freeColClient); - setFocusable(true); - setFocusTraversalKeysEnabled(false); - - createKeyBindings(); - createFrame(null, windowBounds); mapViewer.startCursorBlinking(); - logger.info("Canvas created."); + logger.info("Canvas created woth bounds: " + windowBounds); } + // Internals + /** - * Check if there is a map to display. - * - * @return True if there is a map available. + * Toggle windowed flag. */ - private boolean hasMap() { - return this.freeColClient != null - && this.freeColClient.getGame() != null - && this.freeColClient.getGame().getMap() != null; - } - - public boolean isWindowed() { - return windowed; + private void toggleWindowed() { + this.windowed = !this.windowed; } /** - * Change the windowed mode. + * Create a new frame with a given menu bar and bounds. + * + * @param menuBar The new frames {@code JMenuBar}. + * @param windowBounds The new frame bounding {@code Rectangle}. + * @return The new {@code FreeColFrame}. */ - public void changeWindowedMode() { - // Clean up the old frame - JMenuBar menuBar = null; - Rectangle windowBounds = null; - if (frame != null) { - menuBar = frame.getJMenuBar(); - if (windowed) { - windowBounds = frame.getBounds(); - } - frame.setVisible(false); - frame.dispose(); - } - windowed = !windowed; - - createFrame(menuBar, windowBounds); - } - - private void createFrame(JMenuBar menuBar, Rectangle windowBounds) { + private FreeColFrame createFrame(JMenuBar menuBar, Rectangle windowBounds) { // FIXME: Check this: // User might have moved window to new screen in a // multi-screen setup, so make this.gd point to the current screen. - frame = new FreeColFrame(freeColClient, graphicsDevice, - menuBar, this, windowed, windowBounds); - updateSizes(); - frame.setVisible(true); - } - - /** - * Start the GUI for the map editor. - */ - public void startMapEditorGUI() { - if (frame == null) return; - - frame.setMapEditorMenuBar(); - showMapEditorTransformPanel(); - - CanvasMapEditorMouseListener listener - = new CanvasMapEditorMouseListener(freeColClient, this); - addMouseListener(listener); - addMouseMotionListener(listener); + FreeColFrame fcf + = new FreeColFrame(this.freeColClient, this.graphicsDevice, + menuBar, isWindowed(), windowBounds); + fcf.getContentPane().add(this); + fcf.setVisible(true); + return fcf; } /** - * Quit the GUI. All that is required is to exit the full screen. + * Destroy the current frame. */ - public void quit() { - if (frame != null && !windowed) { - frame.exitFullScreen(); + private void destroyFrame() { + if (this.parentFrame != null) { + this.parentFrame.setVisible(false); + if (!isWindowed()) this.parentFrame.exitFullScreen(); + this.parentFrame.dispose(); + this.parentFrame = null; } } /** - * In game initializations. - */ - public void initializeInGame() { - if (frame == null) return; - frame.setInGameMenuBar(); - } - - /** - * Reset the menu bar. - */ - public void resetMenuBar() { - if (frame == null) return; - this.freeColClient.updateActions(); - frame.resetMenuBar(); - } - - /** - * Update the menu bar. - */ - public void updateMenuBar() { - if (frame == null) return; - this.freeColClient.updateActions(); - frame.updateMenuBar(); - } - - /** - * Scroll the map in the given direction. - * - * @param direction The {@code Direction} to scroll in. - * @return True if scrolling occurred. - */ - public boolean scrollMap(Direction direction) { - return mapViewer.scrollMap(direction); - } - - /** - * Converts the given screen coordinates to Map coordinates. - * It checks to see to which Tile the given pixel 'belongs'. - * - * @param x The x-coordinate in pixels. - * @param y The y-coordinate in pixels. - * @return The Tile that is located at the given position on the screen. - */ - public Tile convertToMapTile(int x, int y) { - return mapViewer.convertToMapTile(x, y); - } - - /** - * Gets the point at which the map was clicked for a drag. - * - * @return The Point where the mouse was initially clicked. - */ - public Point getDragPoint() { - return this.dragPoint; - } - - /** - * Sets the point at which the map was clicked for a drag. - * - * @param x The mouse x position. - * @param y The mouse y position. - */ - public void setDragPoint(int x, int y) { - this.dragPoint = new Point(x, y); - } - - /** - * Is mouse movement differnce above the drag threshold? - * - * @param x The new mouse x position. - * @param y The new mouse y position. - * @return True if the mouse has been dragged. - */ - public boolean isDrag(int x, int y) { - final Point drag = getDragPoint(); - if (drag == null) return false; - int deltaX = Math.abs(x - drag.x); - int deltaY = Math.abs(y - drag.y); - return deltaX >= DRAG_THRESHOLD || deltaY >= DRAG_THRESHOLD; - } - - /** - * Checks if there is currently a goto operation on the mapboard. + * Has the canvas been resized? * - * @return True if a goto operation is in progress. - */ - public boolean isGotoStarted() { - return this.gotoStarted; - } - - /** - * Starts a goto operation. + * @return The new {@code Dimension} for the canvas. */ - public void startGoto() { - this.gotoStarted = true; - setCursor(GO_CURSOR); - mapViewer.changeGotoPath(null); - refresh(); + private Dimension checkResize() { + Dimension newSize = getSize(); + if (this.oldSize.width == newSize.width + && this.oldSize.height == newSize.height) return null; + + this.oldSize = newSize; + return newSize; } /** - * Stops any ongoing goto operation. + * Determine whether to use full screen or windowed mode. * - * @return The old goto path if any. + * @param gd The {@code GraphicsDevice} to display to. + * @param desiredSize An optional window {@code Dimension}. + * @return Null if full screen is to be used, otherwise a window + * bounds {@code Rectangle} */ - public PathNode stopGoto() { - PathNode ret = (this.gotoStarted) ? mapViewer.getGotoPath() : null; - this.gotoStarted = false; - setCursor(null); - mapViewer.changeGotoPath(null); - refresh(); + private static boolean checkWindowed(GraphicsDevice gd, + Dimension desiredSize) { + boolean ret; + if (desiredSize == null) { + if (gd.isFullScreenSupported()) { + logger.info("Full screen mode used."); + ret = false; + } else { + logger.warning("Full screen mode not supported."); + System.err.println(Messages.message("client.fullScreen")); + ret = true; + } + } else { + logger.info("Windowed mode used."); + ret = true; + } return ret; } - /** - * Change the goto path for a unit to a new tile. - * - * @param unit The {@code Unit} that is travelling. - * @param tile The new {@code Tile} to go to. - */ - public void changeGoto(Unit unit, Tile tile) { - if (!isGotoStarted()) return; - - // Do nothing if the tile has not changed. - PathNode oldPath = mapViewer.getGotoPath(); - Tile lastTile = (oldPath == null) ? null - : oldPath.getLastNode().getTile(); - if (lastTile == tile) return; - - // Do not show a path if it will be invalid, avoiding calling - // the expensive path finder if possible. - PathNode newPath = (unit.getTile() == tile - || !tile.isExplored() - || !unit.getSimpleMoveType(tile).isLegal()) ? null - : unit.findPath(tile); - mapViewer.changeGotoPath(newPath); - } - - - // Internals - /** * Adds a component on this Canvas inside a frame. * @@ -853,30 +574,6 @@ private Point getClearSpace(final int x, final int y, return best; } - /** - * Gets any currently displayed colony panel for the specified colony. - * - * This is distinct from {@link #getExistingFreeColPanel} because - * there can be multiple ColonyPanels. - * - * @param colony The {@code Colony} to check. - * @return A currently displayed colony panel, or null if not found. - */ - private ColonyPanel getColonyPanel(Colony colony) { - for (Component c1 : getComponents()) { - if (c1 instanceof JInternalFrame) { - for (Component c2 : ((JInternalFrame) c1).getContentPane() - .getComponents()) { - if (c2 instanceof ColonyPanel - && ((ColonyPanel)c2).getColony() == colony) { - return (ColonyPanel)c2; - } - } - } - } - return null; - } - /** * Gets the internal frame for the given component. * @@ -950,33 +647,18 @@ private Dimension getSavedSize(Component comp) { * to be saved. * * @param c The closing {@code Component}. - * @param frame The enclosing {@code JInternalFrame}. + * @param jif The enclosing {@code JInternalFrame}. */ - private void notifyClose(Component c, JInternalFrame frame) { - if (frame == null) return; - + private void notifyClose(Component c, JInternalFrame jif) { if (c instanceof FreeColPanel) { FreeColPanel fcp = (FreeColPanel)c; fcp.firePropertyChange("closing", false, true); - savePosition(fcp, frame.getLocation()); + savePosition(fcp, jif.getLocation()); saveSize(fcp, fcp.getSize()); } } - /** - * Remove the panels derived from the EuropePanel. - */ - private void removeEuropeanSubpanels() { - FreeColPanel panel; - if ((panel = getExistingFreeColPanel(RecruitPanel.class)) != null) - removeFromCanvas(panel); - if ((panel = getExistingFreeColPanel(PurchasePanel.class)) != null) - removeFromCanvas(panel); - if ((panel = getExistingFreeColPanel(TrainPanel.class)) != null) - removeFromCanvas(panel); - } - /** * Save an {@code int} value to the saved ClientOptions, * using the name of the components class plus the given key as @@ -1056,173 +738,30 @@ private void stopBlinking() { mapViewer.stopCursorBlinking(); } + // Dialog display, only public for Widgets + /** - * Displays the given dialog, optionally making sure a tile is visible. + * Gets any currently displayed colony panel for the specified colony. * - * @param The type to be returned from the dialog. - * @param freeColDialog The dialog to be displayed - * @param tile An optional {@code Tile} to make visible (not - * under the dialog!) - * @return The {@link FreeColDialog#getResponse reponse} returned by - * the dialog. - */ - private T showFreeColDialog(FreeColDialog freeColDialog, - Tile tile) { - viewFreeColDialog(freeColDialog, tile); - T response = freeColDialog.getResponse(); - remove(freeColDialog); - dialogRemove(freeColDialog); - if (freeColDialog.isModal()) restartBlinking(); - return response; - } - - /** - * Displays the given panel, making sure a tile is visible. + * This is distinct from {@link #getExistingFreeColPanel} because + * there can be multiple ColonyPanels. * - * @param panel The panel to be displayed - * @param tile A {@code Tile} to make visible (not under the panel!) - * @param resizable Should the panel be resizable? - */ - private void showFreeColPanel(FreeColPanel panel, Tile tile, - boolean resizable) { - showSubPanel(panel, setOffsetFocus(tile), resizable); - } - - /** - * Displays a {@code FreeColPanel}. - * - * @param panel {@code FreeColPanel}, panel to show - * @param resizable Should the panel be resizable? - */ - private void showSubPanel(FreeColPanel panel, boolean resizable) { - showSubPanel(panel, PopupPosition.CENTERED, resizable); - } - - /** - * Displays a {@code FreeColPanel} at a generalized position. - * - * @param panel {@code FreeColPanel}, panel to show - * @param popupPosition {@code PopupPosition} The generalized - * position to place the panel. - * @param resizable Should the panel be resizable? - */ - private void showSubPanel(FreeColPanel panel, PopupPosition popupPosition, - boolean resizable) { - repaint(); - addAsFrame(panel, false, popupPosition, resizable); - panel.requestFocus(); - } - - - // Public API - - /** - * Closes all the menus that are currently open. - */ - public void closeMenus() { - for (JInternalFrame frame : getAllFrames()) { - for (Component c : frame.getContentPane().getComponents()) { - notifyClose(c, frame); - } - frame.dispose(); - } - while (!dialogs.isEmpty()) { - FreeColDialog dialog = dialogs.remove(0); - dialog.dispose(); - } - } - - /** - * Close a panel by class name. - * - * @param panel The panel to close. + * @param colony The {@code Colony} to check. + * @return A currently displayed colony panel, or null if not found. */ - public void closePanel(String panel) { - if (panel.endsWith("Panel")) { - for (Component c1 : getComponents()) { - if (c1 instanceof JInternalFrame) { - for (Component c2 : ((JInternalFrame)c1).getContentPane() - .getComponents()) { - if (panel.equals(c2.getClass().getName())) { - notifyClose(c2, (JInternalFrame)c1); - return; - } + public ColonyPanel getColonyPanel(Colony colony) { + for (Component c1 : getComponents()) { + if (c1 instanceof JInternalFrame) { + for (Component c2 : ((JInternalFrame) c1).getContentPane() + .getComponents()) { + if (c2 instanceof ColonyPanel + && ((ColonyPanel)c2).getColony() == colony) { + return (ColonyPanel)c2; } } } - } else if (panel.endsWith("Dialog")) { - for (FreeColDialog fcd : new ArrayList<>(dialogs)) { - if (panel.equals(fcd.getClass().getName())) { - dialogs.remove(fcd); - fcd.dispose(); - return; - } - } - } - } - - /** - * Closes the {@link MainPanel}. - */ - public void closeMainPanel() { - if (mainPanel != null) { - remove(mainPanel); - mainPanel = null; - } - } - - /** - * Closes the {@code StatusPanel}. - * - * @see #showStatusPanel - */ - public void closeStatusPanel() { - if (statusPanel.isVisible()) { - remove(statusPanel); } - } - - /** - * Tells that a chat message was received. - * - * @param message The chat message. - */ - public void displayChat(GUIMessage message) { - chatDisplay.addMessage(message); - repaint(0, 0, getWidth(), getHeight()); - } - - /** - * Tells that a chat message was received. - * - * @param senderName The sender. - * @param message The chat message. - * @param privateChat True if this is a private message. - */ - public void displayStartChat(String senderName, String message, - boolean privateChat) { - StartGamePanel sgp = getExistingFreeColPanel(StartGamePanel.class); - if (sgp != null) { - sgp.displayChat(senderName, message, privateChat); - } - } - - /** - * Add a dialog to the current dialog list. - * - * @param fcd The dialog to add. - */ - private void dialogAdd(FreeColDialog fcd) { - dialogs.add(fcd); - } - - /** - * Remove a dialog from the current dialog list. - * - * @param fcd The dialog to remove. - */ - public void dialogRemove(FreeColDialog fcd) { - dialogs.remove(fcd); + return null; } /** @@ -1233,7 +772,7 @@ public void dialogRemove(FreeColDialog fcd) { * @return A currently displayed {@code FreeColPanel} of the * requested type, or null if none found. */ - private T getExistingFreeColPanel(Class type) { + public T getExistingFreeColPanel(Class type) { for (Component c1 : getComponents()) { if (c1 instanceof JInternalFrame) { for (Component c2 : ((JInternalFrame)c1).getContentPane() @@ -1256,360 +795,73 @@ private T getExistingFreeColPanel(Class type) { } /** - * Get any panel this {@code Canvas} is displaying. + * Get a currentlydisplayed FreeColDialog of a given type. * - * @return A {@code Component} the {@code Canvas} is - * displaying, or null if none found. + * @param type The class of dialog to look for. + * @return The {@code FreeColDialog} found, or null if none present. */ - public Component getShowingSubPanel() { - for (Component c : getComponents()) { - if (c instanceof ToolBoxFrame) { - continue; - } - if (c instanceof JInternalFrame) { - return c; - } else if (c instanceof JInternalFrame.JDesktopIcon) { - return c; - } + public FreeColDialog getExistingFreeColDialog(Class type) { + for (FreeColDialog d : dialogs) { + if (d.getClass() == type) return d; } return null; } /** - * Checks if a client options dialog is present. - * - * @return True if the client options are showing. - */ - public boolean isClientOptionsDialogShowing() { - return clientOptionsDialogShowing; - } - - /** - * Attach a closing callback to any current error panel. + * Displays the given dialog, optionally making sure a tile is visible. * - * @param callback The {@code Runnable} to attach. - * @return True if an error panel was present. + * @param The type to be returned from the dialog. + * @param freeColDialog The dialog to be displayed + * @param tile An optional {@code Tile} to make visible (not + * under the dialog!) + * @return The {@link FreeColDialog#getResponse reponse} returned by + * the dialog. */ - public boolean onClosingErrorPanel(Runnable callback) { - ErrorPanel ep = getExistingFreeColPanel(ErrorPanel.class); - if (ep == null) return false; - ep.addClosingCallback(callback); - return true; + public T showFreeColDialog(FreeColDialog freeColDialog, + Tile tile) { + viewFreeColDialog(freeColDialog, tile); + T response = freeColDialog.getResponse(); + remove(freeColDialog); + dialogRemove(freeColDialog); + if (freeColDialog.isModal()) restartBlinking(); + return response; } /** - * Checks if this {@code Canvas} displaying another panel. - *

- * Note that the previous implementation could throw exceptions - * in some cases, thus the change. + * Displays the given panel, making sure a tile is visible. * - * @return {@code true} if the {@code Canvas} is displaying an - * internal frame. - */ - private boolean isShowingSubPanel() { - return getShowingSubPanel() != null; - } - - /** - * Refresh this canvas. + * @param panel The panel to be displayed + * @param tile A {@code Tile} to make visible (not under the panel!) + * @param resizable Should the panel be resizable? */ - public void refresh() { - repaint(0, 0, getWidth(), getHeight()); + public void showFreeColPanel(FreeColPanel panel, Tile tile, + boolean resizable) { + showSubPanel(panel, setOffsetFocus(tile), resizable); } /** - * Removes the given component from this canvas without - * updating the menu bar. + * Displays a {@code FreeColPanel}. * - * @param comp The {@code Component} to remove. - */ - public void removeFromCanvas(Component comp) { - if (comp == null) return; - - final Rectangle updateBounds = comp.getBounds(); - final JInternalFrame frame = getInternalFrame(comp); - notifyClose(comp, frame); - if (frame != null && frame != comp) { - frame.dispose(); - } else { - // Java 1.7.0 as seen on Fedora with: - // Java version: 1.7.0_40 - // Java WM version: 24.0-b56 - // crashes here deep in the java libraries. - try { - super.remove(comp); - } catch (Exception e) { - logger.log(Level.WARNING, "Java crash", e); - } - } - repaint(updateBounds.x, updateBounds.y, - updateBounds.width, updateBounds.height); - } - - /** - * Removes components that is only used when in game. + * @param panel {@code FreeColPanel}, panel to show + * @param resizable Should the panel be resizable? */ - public void removeInGameComponents() { - // remove listeners, they will be added when launching the new game... - KeyListener[] keyListeners = getKeyListeners(); - for (KeyListener keyListener : keyListeners) { - removeKeyListener(keyListener); - } - - MouseListener[] mouseListeners = getMouseListeners(); - for (MouseListener mouseListener : mouseListeners) { - removeMouseListener(mouseListener); - } - - MouseMotionListener[] mouseMotionListeners = getMouseMotionListeners(); - for (MouseMotionListener mouseMotionListener : mouseMotionListeners) { - removeMouseMotionListener(mouseMotionListener); - } - - for (Component c : getComponents()) { - removeFromCanvas(c); - } + public void showSubPanel(FreeColPanel panel, boolean resizable) { + showSubPanel(panel, PopupPosition.CENTERED, resizable); } /** - * Set preferred size to saved size, or to the given - * {@code Dimension} if no saved size was found. Call this - * method in the constructor of a FreeColPanel in order to - * remember its size and position. + * Displays a {@code FreeColPanel} at a generalized position. * - * @param comp The {@code Component} to use. - * @param d The {@code Dimension} to use as default. - */ - public void restoreSavedSize(Component comp, Dimension d) { - final Dimension pref = comp.getPreferredSize(); - final Dimension sugg = (d == null) ? pref : d; - boolean save = false; - - Dimension size = getSavedSize(comp); - if (size == null) { - size = new Dimension(pref); - save = true; - } - - // Fix up broken/outdated saved sizes - if(size.width < sugg.width) { - size.width = sugg.width; - save = true; - } - if(size.height < sugg.height) { - size.height = sugg.height; - save = true; - } - if(size.width < pref.width) { - size.width = pref.width; - save = true; - } - if(size.height < pref.height) { - size.height = pref.height; - save = true; - } - - if(save) { - saveSize(comp, size); - } - - if (!pref.equals(size)) { - comp.setPreferredSize(size); - } - } - - /** - * Closes all panels, changes the background and shows the main menu. + * @param panel {@code FreeColPanel}, panel to show + * @param popupPosition {@code PopupPosition} The generalized + * position to place the panel. + * @param resizable Should the panel be resizable? */ - public void mainTitle() { - // FIXME: check if the GUI object knows that we're not - // inGame. (Retrieve value of GUI::inGame.) If GUI thinks - // we're still in the game then log an error because at this - // point the GUI should have been informed. - removeInGameComponents(); - showMainPanel(); + public void showSubPanel(FreeColPanel panel, PopupPosition popupPosition, + boolean resizable) { repaint(); - } - - public void setupMouseListeners() { - addMouseListener(new CanvasMouseListener(freeColClient)); - addMouseMotionListener(new CanvasMouseMotionListener(freeColClient, this)); - } - - /** - * Updates the sizes of the components on this Canvas. - */ - private void updateSizes() { - if (oldSize == null - || oldSize.width != getWidth() - || oldSize.height != getHeight()) { - gui.updateMapControlsInCanvas(); - mapViewer.changeSize(getSize()); - oldSize = getSize(); - } - } - - // Override JComponent - - /** - * {@inheritDoc} - */ - @Override - public void paintComponent(Graphics g) { - updateSizes(); - Graphics2D g2d = (Graphics2D) g; - chatDisplay.removeOldMessages(); - Dimension size = getSize(); - - if (freeColClient.isMapEditor()) { - if (hasMap()) { - mapViewer.displayMap(g2d); - } else { - g2d.setColor(Color.BLACK); - g2d.fillRect(0, 0, size.width, size.height); - } - - } else if (freeColClient.isInGame() && hasMap()) { - mapViewer.displayMap(g2d); - - // Toggle grey layer - if (freeColClient.currentPlayerIsMyPlayer()) { - if (greyLayer.getParent() != null) { - removeFromCanvas(greyLayer); - } - } else { - greyLayer.setBounds(0, 0, size.width, size.height); - greyLayer.setPlayer(freeColClient.getGame().getCurrentPlayer()); - if (greyLayer.getParent() == null) { - addToCanvas(greyLayer, JLayeredPane.DRAG_LAYER); - } - } - - // paint chat display - chatDisplay.display(g2d, mapViewer.getImageLibrary(), size); - - } else { - /* main menu */ - // TODO: Check if its right to sometimes have an unfocused map - // ingame and end up here after clicking outside map. - final Image bgImage = ImageLibrary.getCanvasBackgroundImage(); - if (bgImage != null) { - // Get the background without scaling, to avoid wasting - // memory needlessly keeping an unbounded number of rescaled - // versions of the largest image in FreeCol, forever. - // Draw background image with scaling. - g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR); - g2d.drawImage(bgImage, 0, 0, size.width, size.height, this); - String versionStr = "v. " + FreeCol.getVersion(); - Font oldFont = g2d.getFont(); - Color oldColor = g2d.getColor(); - Font newFont = oldFont.deriveFont(Font.BOLD); - TextLayout layout = new TextLayout(versionStr, newFont, - g2d.getFontRenderContext()); - Rectangle2D bounds = layout.getBounds(); - float x = size.width - (float) bounds.getWidth() - 5; - float y = size.height - (float) bounds.getHeight(); - g2d.setColor(Color.white); - layout.draw(g2d, x, y); - g2d.setFont(oldFont); - g2d.setColor(oldColor); - } else { - g2d.setColor(Color.BLACK); - g2d.fillRect(0, 0, size.width, size.height); - } - } - } - - - // Override Container - - /** - * {@inheritDoc} - */ - @Override - public void remove(Component comp) { - removeFromCanvas(comp); - updateMenuBar(); - } - - - // Special handling for the startGamePanel. - - /** - * Refresh the player's table (called when a new player is added - * from PreGameInputHandler.addPlayer). - */ - void refreshPlayersTable() { - startGamePanel.refreshPlayersTable(); - } - - - // Dialog display - - /** - * Displays a modal dialog with text and a choice of options. - * - * @param The type to be returned from the dialog. - * @param tile An optional {@code Tile} to make visible (not - * under the dialog!) - * @param obj An object that explains the choice for the user. - * @param icon An optional icon to display. - * @param cancelKey Key for the text of the optional cancel button. - * @param choices The {@code List} containing the ChoiceItems to - * create buttons for. - * @return The corresponding member of the values array to the selected - * option, or null if no choices available. - */ - public T showChoiceDialog(Tile tile, StringTemplate tmpl, - ImageIcon icon, String cancelKey, - List> choices) { - if (choices.isEmpty()) return null; - FreeColChoiceDialog fcd - = new FreeColChoiceDialog<>(freeColClient, frame, true, tmpl, icon, - cancelKey, choices); - return showFreeColDialog(fcd, tile); - } - - /** - * Displays a modal dialog with a text and a ok/cancel option. - * - * @param tile An optional {@code Tile} to make visible (not - * under the dialog!) - * @param template A {@code StringTemplate} to explain the choice. - * @param icon An optional icon to display. - * @param okKey The text displayed on the "ok"-button. - * @param cancelKey The text displayed on the "cancel"-button. - * @return True if the user clicked the "ok"-button. - */ - public boolean showConfirmDialog(Tile tile, StringTemplate template, - ImageIcon icon, - String okKey, String cancelKey) { - FreeColConfirmDialog fcd - = new FreeColConfirmDialog(freeColClient, frame, true, template, - icon, okKey, cancelKey); - return showFreeColDialog(fcd, tile); - } - - /** - * Displays a modal dialog with a text field and a ok/cancel option. - * - * @param tile An optional tile to make visible (not under the dialog). - * @param template A {@code StringTemplate} that explains the - * action to the user. - * @param defaultValue The default value appearing in the text field. - * @param okKey A key displayed on the "ok"-button. - * @param cancelKey A key displayed on the optional "cancel"-button. - * @return The text the user entered, or null if cancelled. - */ - public String showInputDialog(Tile tile, StringTemplate template, - String defaultValue, - String okKey, String cancelKey) { - FreeColStringInputDialog fcd - = new FreeColStringInputDialog(freeColClient, frame, true, - template, defaultValue, - okKey, cancelKey); - return showFreeColDialog(fcd, tile); + addAsFrame(panel, false, popupPosition, resizable); + panel.requestFocus(); } /** @@ -1620,13 +872,13 @@ public String showInputDialog(Tile tile, StringTemplate template, * @param tile An optional {@code Tile} to make visible (not * under the dialog!) */ - private void viewFreeColDialog(final FreeColDialog freeColDialog, - Tile tile) { + public void viewFreeColDialog(final FreeColDialog freeColDialog, + Tile tile) { PopupPosition pp = setOffsetFocus(tile); // TODO: Remove compatibility code when all non-modal dialogs // have been converted into panels. - if(!freeColDialog.isModal()) { + if (!freeColDialog.isModal()) { int canvasWidth = getWidth(); int dialogWidth = freeColDialog.getWidth(); if(dialogWidth*2 <= canvasWidth) { @@ -1648,790 +900,615 @@ private void viewFreeColDialog(final FreeColDialog freeColDialog, } - // Simple front ends to display each panel or dialog. - - public void removeTradeRoutePanel(TradeRoutePanel panel) { - remove(panel); - TradeRouteInputPanel trip - = getExistingFreeColPanel(TradeRouteInputPanel.class); - if (trip != null) trip.cancelTradeRoute(); - } - - /** - * Display the AboutPanel. - */ - public void showAboutPanel() { - showSubPanel(new AboutPanel(freeColClient), false); - } - - /** - * Show the BuildQueuePanel for a given colony. - * - * @param colony The {@code Colony} to show the build queue of. - * @return The {@code BuildQueuePanel}. - */ - public BuildQueuePanel showBuildQueuePanel(Colony colony) { - BuildQueuePanel panel = getExistingFreeColPanel(BuildQueuePanel.class); - if (panel == null || panel.getColony() != colony) { - panel = new BuildQueuePanel(freeColClient, colony); - showSubPanel(panel, true); - } - return panel; - } - - /** - * Display the {@code CaptureGoodsDialog}. - * - * @param unit The {@code Unit} capturing goods. - * @param gl The list of {@code Goods} to choose from. - * @param handler A {@code DialogHandler} for the dialog response. - */ - public void showCaptureGoodsDialog(Unit unit, List gl, - DialogHandler> handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new CaptureGoodsDialog(freeColClient, frame, unit, gl), - null, handler)); - } + // Frames and windowing /** - * Displays the {@code ChatPanel}. + * Are we in windowed mode? * - * @see ChatPanel + * @return True if in windowed mode. */ - public void showChatPanel() { - // FIXME: does it have state, or can we create a new one? - if (freeColClient.getSinglePlayer()) return; // chat with who? - showSubPanel(chatPanel, true); + public boolean isWindowed() { + return this.windowed; } /** - * Displays the {@code ChooseFoundingFatherDialog}. + * Get the parent frame. * - * @param ffs The {@code FoundingFather}s to choose from. - * @param handler A {@code DialogHandler} for the dialog response. + * Do not use this except inside Widgets (which is really just an + * extension of Canvas). + * + * @return The parent {@code FreeColFrame}. */ - public void showChooseFoundingFatherDialog(List ffs, - DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new ChooseFoundingFatherDialog(freeColClient, frame, ffs), - null, handler)); + public FreeColFrame getParentFrame() { + return this.parentFrame; } - + /** - * Displays a dialog for setting client options. - * - * @return The modified {@code OptionGroup}, or null if not modified. + * Toggle the frame between windowed and non-windowed modes. */ - public OptionGroup showClientOptionsDialog() { - ClientOptionsDialog dialog = new ClientOptionsDialog(freeColClient, frame); - OptionGroup group = null; - clientOptionsDialogShowing = true; - try { - group = showFreeColDialog(dialog, null); - } finally { - clientOptionsDialogShowing = false; + public void toggleFrame() { + JMenuBar menuBar = null; + Rectangle windowBounds = null; + if (this.parentFrame != null) { + menuBar = this.parentFrame.getJMenuBar(); + windowBounds = this.parentFrame.getBounds(); } - return group; + destroyFrame(); + toggleWindowed(); + this.parentFrame = createFrame(menuBar, windowBounds); } - /** - * Displays the colony panel of the given {@code Colony}. - * Defends against duplicates as this can duplicate messages - * generated by multiple property change listeners registered - * against the same colony. - * - * @param colony The colony whose panel needs to be displayed. - * @param unit An optional {@code Unit} to select within the panel. - * @return The {@code ColonyPanel}. - */ - public ColonyPanel showColonyPanel(Colony colony, Unit unit) { - if (colony == null) return null; - ColonyPanel panel = getColonyPanel(colony); - if (panel == null) { + // Map controls + + public boolean canZoomInMapControls() { + return mapControls != null && mapControls.canZoomInMapControls(); + } + + public boolean canZoomOutMapControls() { + return mapControls != null && mapControls.canZoomOutMapControls(); + } + + public void enableMapControls(boolean enable) { + // Always instantiate in game. + if (enable && mapControls == null) { + String className = this.freeColClient.getClientOptions() + .getString(ClientOptions.MAP_CONTROLS); + final String panelName = "net.sf.freecol.client.gui.panel." + + lastPart(className, "."); try { - panel = new ColonyPanel(freeColClient, colony); - } catch (Exception e) { - logger.log(Level.WARNING, "Exception in ColonyPanel for " - + colony.getId(), e); - return null; + mapControls = (MapControls)Introspector.instantiate(panelName, + new Class[] { FreeColClient.class }, + new Object[] { this.freeColClient }); + mapControls.addToComponent(this); + mapControls.update(); + logger.info("Instantiated " + panelName); + } catch (Introspector.IntrospectorException ie) { + logger.log(Level.WARNING, "Failed in make map controls for: " + + panelName, ie); } - showFreeColPanel(panel, colony.getTile(), true); - } else { - panel.requestFocus(); + } else if (!enable && mapControls != null) { + mapControls.removeFromComponent(this); + mapControls = null; } - if (unit != null) panel.setSelectedUnit(unit); - return panel; } - /** - * Show the colopedia entry for a given node. - * - * @param nodeId The node identifier to display. - */ - public void showColopediaPanel(String nodeId) { - showSubPanel(new ColopediaPanel(freeColClient, nodeId), true); + public void miniMapToggleViewControls() { + if (mapControls == null) return; + mapControls.toggleView(); } - /** - * Show a {@code ColorChooserPanel}. - * - * @param al An {@code ActionListener} to handle panel button - * presses. - * @return The {@code ColorChooserPanel} created. - */ - public ColorChooserPanel showColorChooserPanel(ActionListener al) { - ColorChooserPanel ccp = new ColorChooserPanel(freeColClient, al); - showFreeColPanel(ccp, null, false); - return ccp; + public void miniMapToggleFogOfWarControls() { + if (mapControls == null) return; + mapControls.toggleFogOfWar(); } - /** - * Show the compact labour report. - */ - public void showCompactLabourReport() { - CompactLabourReport details = new CompactLabourReport(freeColClient); - details.initialize(); - showSubPanel(details, false); - + public void updateMapControls() { + if (mapControls != null) mapControls.update(); } - /** - * Show the compact labour report for the specified unit data. - * - * @param unitData The {@code UnitData} to display. - */ - public void showCompactLabourReport(UnitData unitData) { - CompactLabourReport details = new CompactLabourReport(freeColClient, - unitData); - details.initialize(); - showSubPanel(details, false); + public void updateMapControlsInCanvas() { + if (mapControls == null) return; + mapControls.removeFromComponent(this); + mapControls.addToComponent(this); } - /** - * Display a dialog to confirm a declaration of independence. - * - * @return A list of names for a new nation. - */ - public List showConfirmDeclarationDialog() { - return showFreeColDialog(new ConfirmDeclarationDialog(freeColClient, frame), - null); + public void zoomInMapControls() { + if (mapControls == null) return; + mapControls.zoomIn(); } - /** - * Display a panel showing the declaration of independence with - * animated signature. - */ - public void showDeclarationPanel() { - showSubPanel(new DeclarationPanel(freeColClient), - PopupPosition.CENTERED, false); + public void zoomOutMapControls() { + if (mapControls == null) return; + mapControls.zoomOut(); } + // Map viewer + /** - * Display the difficulty dialog for a given group. + * Scroll the map in the given direction. * - * @param spec The enclosing {@code Specification}. - * @param group The {@code OptionGroup} containing the difficulty. - * @param editable If the options should be editable. - * @return The resulting {@code OptionGroup}. - */ - public OptionGroup showDifficultyDialog(Specification spec, - OptionGroup group, boolean editable) { - DifficultyDialog dd = new DifficultyDialog(freeColClient, frame, - spec, group, editable); - OptionGroup ret = showFreeColDialog(dd, null); - if (ret != null) FreeCol.setDifficulty(ret); - return ret; - } - - /** - * Displays the {@code DumpCargoDialog}. + * Called from ScrollThread. * - * @param unit The {@code Unit} that is dumping. - * @param handler A {@code DialogHandler} for the dialog response. + * @param direction The {@code Direction} to scroll in. + * @return True if scrolling occurred. */ - public void showDumpCargoDialog(Unit unit, DialogHandler> handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new DumpCargoDialog(freeColClient, frame, unit), - unit.getTile(), handler)); + public boolean scrollMap(Direction direction) { + return mapViewer.scrollMap(direction); } /** - * Display the EditOptionDialog. + * Converts the given screen coordinates to Map coordinates. + * It checks to see to which Tile the given pixel 'belongs'. * - * @param op The {@code Option} to edit. - * @return The response returned by the dialog. + * @param x The x-coordinate in pixels. + * @param y The y-coordinate in pixels. + * @return The Tile that is located at the given position on the screen. */ - public boolean showEditOptionDialog(Option op) { - return (op == null) ? false - : showFreeColDialog(new EditOptionDialog(freeColClient, frame, op), - null); + public Tile convertToMapTile(int x, int y) { + return mapViewer.convertToMapTile(x, y); } + // Gotos + /** - * Display the EditSettlementDialog. + * Checks if there is currently a goto operation on the mapboard. * - * @param is The {@code IndianSettlement} to edit. + * @return True if a goto operation is in progress. */ - public void showEditSettlementDialog(IndianSettlement is) { - showFreeColDialog(new EditSettlementDialog(freeColClient, frame, is), - null); + public boolean isGotoStarted() { + return this.gotoStarted; } /** - * Shows the panel that allows the user to choose which unit will emigrate - * from Europe. - * - * @param player The {@code Player} whose unit is emigrating. - * @param fountainOfYouth Is this dialog displayed as a result of a - * fountain of youth. - * @param handler A {@code DialogHandler} for the dialog response. + * Starts a goto operation. */ - public void showEmigrationDialog(Player player, boolean fountainOfYouth, - DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new EmigrationDialog(freeColClient, frame, player.getEurope(), - fountainOfYouth), - null, handler)); + public void startGoto() { + this.gotoStarted = true; + setCursor(GO_CURSOR); + mapViewer.changeGotoPath(null); + refresh(); } /** - * Display the EndTurnDialog with given units that could still move. + * Stops any ongoing goto operation. * - * @param units A list of {@code Unit}s that could still move. - * @param handler A {@code DialogHandler} for the dialog response. + * @return The old goto path if any. */ - public void showEndTurnDialog(List units, - DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new EndTurnDialog(freeColClient, frame, units), - null, handler)); + public PathNode stopGoto() { + PathNode ret = (this.gotoStarted) ? mapViewer.getGotoPath() : null; + this.gotoStarted = false; + setCursor(null); + mapViewer.changeGotoPath(null); + refresh(); + return ret; } - /** - * Displays an error message. - * - * @param message The message to display. - * @param callback Optional routine to run when the error panel is closed. - */ - public void showErrorMessage(String message, Runnable callback) { - if (message != null) { - ErrorPanel errorPanel = new ErrorPanel(freeColClient, message); - if (callback != null) errorPanel.addClosingCallback(callback); - showSubPanel(errorPanel, true); - } - } + // Startup /** - * Displays the {@code EuropePanel}. + * Play the opening video. * - * @see EuropePanel - */ - public void showEuropePanel() { - if (freeColClient.getGame() == null) return; - EuropePanel panel = getExistingFreeColPanel(EuropePanel.class); - if (panel == null) { - panel = new EuropePanel(freeColClient, (getHeight() > 780)); - panel.addClosingCallback(() -> { removeEuropeanSubpanels(); }); - showSubPanel(panel, true); + * @param videoId An identifier for the video content. + * @param muteAudio Mute if true. + * @param runnable A {@code Runnable} to run on completion. + */ + public void playVideo(String videoId, boolean muteAudio, + final Runnable runnable) { + final Video video = ImageLibrary.getVideo(videoId); + final VideoComponent vc = new VideoComponent(video, muteAudio); + + final class AbortListener implements ActionListener, KeyListener, + MouseListener, VideoListener { + + private Timer t = null; + + @Override + public void keyPressed(KeyEvent e) { + } + + @Override + public void keyReleased(KeyEvent e1) { + execute(); + } + + @Override + public void keyTyped(KeyEvent e2) { + } + + @Override + public void mouseClicked(MouseEvent e3) { + execute(); + } + + @Override + public void mouseEntered(MouseEvent e4) { + } + + @Override + public void mouseExited(MouseEvent e5) { + } + + @Override + public void mousePressed(MouseEvent e6) { + } + + @Override + public void mouseReleased(MouseEvent e7) { + } + + @Override + public void stopped() { + execute(); + } + + @Override + public void actionPerformed(ActionEvent ae) { // from timer + execute(); + } + + public void startTimer(int tim) { + this.t = new Timer(tim, this); + this.t.setRepeats(false); + this.t.start(); + } + + private void execute() { + removeKeyListener(this); + removeMouseListener(this); + vc.removeMouseListener(this); + vc.stop(); + remove(vc); + if (t != null) { + t.stop(); + } + runnable.run(); + } } + + closeMenus(); + AbortListener l = new AbortListener(); + addMouseListener(l); + addKeyListener(l); + // The Cortado applet is failing to quit when finished, make + // sure it eventually gets kicked. + // Change the magic number if we change the opening video length. + l.startTimer(80000); + + // Add video and play + addCentered(vc, JLayeredPane.PALETTE_LAYER); + vc.play(); } /** - * Display an event panel. - * - * @param header The title. - * @param image A resource key for the image to display. - * @param footer Optional footer text. + * Map editor initialization. */ - public void showEventPanel(String header, String image, String footer) { - showSubPanel(new EventPanel(freeColClient, header, image, footer), - PopupPosition.CENTERED, false); + public void startMapEditorGUI() { + this.parentFrame.setMenuBar(new MapEditorMenuBar(this.freeColClient, + new MenuMouseMotionListener(this.freeColClient, this))); + CanvasMapEditorMouseListener listener + = new CanvasMapEditorMouseListener(freeColClient, this); + addMouseListener(listener); + addMouseMotionListener(listener); } /** - * Display the FindSettlementPanel. + * In game initializations. */ - public void showFindSettlementPanel() { - showSubPanel(new FindSettlementPanel(freeColClient), - PopupPosition.ORIGIN, true); + public void initializeInGame() { + this.parentFrame.setMenuBar(new InGameMenuBar(this.freeColClient, + new MenuMouseMotionListener(this.freeColClient, this))); + addMouseListener(new CanvasMouseListener(this.freeColClient)); + addMouseMotionListener(new CanvasMouseMotionListener(this.freeColClient, this)); } /** - * Display the first contact dialog (which is really just a - * non-modal confirm dialog). - * - * @param player The {@code Player} making contact. - * @param other The {@code Player} to contact. - * @param tile An optional {@code Tile} on offer. - * @param settlementCount The number of settlements the other - * player has (from the server, other.getNumberOfSettlements() - * is wrong here!). - * @param handler A {@code DialogHandler} for the dialog response. - */ - public void showFirstContactDialog(Player player, Player other, - Tile tile, int settlementCount, - DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new FirstContactDialog(freeColClient, frame, player, other, tile, - settlementCount), - tile, handler)); - } - - /** - * Display the GameOptionsDialog. - * - * @param editable Should the game options be editable? - * @return The {@code OptionGroup} selected. + * Reset the menu bar. */ - public OptionGroup showGameOptionsDialog(boolean editable) { - GameOptionsDialog god = new GameOptionsDialog(freeColClient, frame, editable); - return showFreeColDialog(god, null); + public void resetMenuBar() { + this.freeColClient.updateActions(); + this.parentFrame.resetMenuBar(); } /** - * Displays the high scores panel. - * - * @param messageId An optional message to add to the high scores panel. - * @param scores The list of {@code HighScore}s to display. + * Update the menu bar. */ - public void showHighScoresPanel(String messageId, List scores) { - showSubPanel(new ReportHighScoresPanel(freeColClient, messageId, scores), - PopupPosition.CENTERED, true); + public void updateMenuBar() { + this.freeColClient.updateActions(); + this.parentFrame.updateMenuBar(); } /** - * Displays the panel of the given native settlement. - * - * @param is The {@code IndianSettlement} to display. + * Quit the canvas. */ - public void showIndianSettlementPanel(IndianSettlement is) { - IndianSettlementPanel panel - = new IndianSettlementPanel(freeColClient, is); - showFreeColPanel(panel, is.getTile(), true); + public void quit() { + destroyFrame(); } /** - * Make image icon from an image. - * Use only if you know having null is possible! - * - * @param image The {@code Image} to create an icon for. - * @return The {@code ImageIcon}. + * Closes all the menus that are currently open. */ - private static ImageIcon createImageIcon(Image image) { - return (image==null) ? null : new ImageIcon(image); + public void closeMenus() { + for (JInternalFrame jif : getAllFrames()) { + for (Component c : jif.getContentPane().getComponents()) { + notifyClose(c, jif); + } + jif.dispose(); + } + while (!dialogs.isEmpty()) { + FreeColDialog dialog = dialogs.remove(0); + dialog.dispose(); + } } /** - * Make image icon from an object. + * Close a panel by class name. * - * @param display The FreeColObject to find an icon for. - * @return The {@code ImageIcon} found. + * @param panel The panel to close. */ - private ImageIcon createObjectImageIcon(FreeColObject display) { - return (display == null) ? null - : createImageIcon(gui.getImageLibrary().getObjectImage(display, 2f)); + public void closePanel(String panel) { + if (panel.endsWith("Panel")) { + for (Component c1 : getComponents()) { + if (c1 instanceof JInternalFrame) { + for (Component c2 : ((JInternalFrame)c1).getContentPane() + .getComponents()) { + if (panel.equals(c2.getClass().getName())) { + notifyClose(c2, (JInternalFrame)c1); + return; + } + } + } + } + } else if (panel.endsWith("Dialog")) { + for (FreeColDialog fcd : new ArrayList<>(dialogs)) { + if (panel.equals(fcd.getClass().getName())) { + dialogs.remove(fcd); + fcd.dispose(); + return; + } + } + } } /** - * Shows a message with some information and an "OK"-button. + * Add a dialog to the current dialog list. * - * @param displayObject Optional object for displaying an icon. - * @param template The {@code StringTemplate} to display. - * @return The {@code InformationPanel} that is displayed. - */ - public InformationPanel showInformationPanel(FreeColObject displayObject, - StringTemplate template) { - ImageIcon icon = null; - Tile tile = null; - if (displayObject != null) { - icon = createObjectImageIcon(displayObject); - tile = (displayObject instanceof Location) - ? ((Location)displayObject).getTile() - : null; - } - return showInformationPanel(displayObject, tile, icon, template); + * @param fcd The dialog to add. + */ + private void dialogAdd(FreeColDialog fcd) { + dialogs.add(fcd); } /** - * Shows a message with some information and an "OK"-button. + * Remove a dialog from the current dialog list. * - * @param displayObject Optional object for displaying. - * @param tile The Tile the object is at. - * @param icon The icon to display for the object. - * @param template The {@code StringTemplate} to display. - * @return The {@code InformationPanel} that is displayed. - */ - public InformationPanel showInformationPanel(FreeColObject displayObject, - Tile tile, ImageIcon icon, - StringTemplate template) { - String text = Messages.message(template); - InformationPanel panel = new InformationPanel(freeColClient, text, - displayObject, icon); - showFreeColPanel(panel, tile, true); - return panel; + * @param fcd The dialog to remove. + */ + public void dialogRemove(FreeColDialog fcd) { + dialogs.remove(fcd); } /** - * Displays a dialog where the user may choose a file. + * Get any panel this {@code Canvas} is displaying. * - * @param directory The directory containing the files. - * @param extension An extension to select with. - * @return The selected {@code File}. - */ - public File showLoadDialog(File directory, String extension) { - FileFilter[] filters = new FileFilter[] { - FreeColDataFile.getFileFilter(extension) - }; - File file = null; - for (;;) { - file = showFreeColDialog(new LoadDialog(freeColClient, frame, - directory, filters), null); - if (file == null || file.isFile()) break; - showErrorMessage(Messages.message(FreeCol.badFile("error.noSuchFile", file)), null); + * @return A {@code Component} the {@code Canvas} is + * displaying, or null if none found. + */ + public Component getShowingSubPanel() { + for (Component c : getComponents()) { + if (c instanceof ToolBoxFrame) { + continue; + } + if (c instanceof JInternalFrame) { + return c; + } else if (c instanceof JInternalFrame.JDesktopIcon) { + return c; + } } - return file; + return null; } /** - * Displays a dialog for setting options when loading a savegame. The - * settings can be retrieved directly from {@link LoadingSavegameDialog} - * after calling this method. + * Attach a closing callback to any current error panel. * - * @param pubSer Default value. - * @param single Default value. - * @return The {@code LoadingSavegameInfo} if the dialog was accepted, - * or null otherwise. - */ - public LoadingSavegameInfo showLoadingSavegameDialog(boolean pubSer, - boolean single) { - LoadingSavegameDialog lsd - = new LoadingSavegameDialog(freeColClient, frame); - return (showFreeColDialog(lsd, null)) ? lsd.getInfo() : null; - } - - /** - * Show a panel containing the log file. + * @param callback The {@code Runnable} to attach. + * @return True if an error panel was present. */ - public void showLogFilePanel() { - showSubPanel(new ErrorPanel(freeColClient), true); - + public boolean onClosingErrorPanel(Runnable callback) { + ErrorPanel ep = getExistingFreeColPanel(ErrorPanel.class); + if (ep == null) return false; + ep.addClosingCallback(callback); + return true; } /** - * Shows the {@code MainPanel}. + * Checks if this {@code Canvas} displaying another panel. + *

+ * Note that the previous implementation could throw exceptions + * in some cases, thus the change. + * + * @return {@code true} if the {@code Canvas} is displaying an + * internal frame. */ - public void showMainPanel() { - closeMenus(); - frame.removeMenuBar(); - mainPanel = new MainPanel(freeColClient); - addCentered(mainPanel, JLayeredPane.DEFAULT_LAYER); - mainPanel.requestFocus(); + private boolean isShowingSubPanel() { + return getShowingSubPanel() != null; } /** - * Display the map editor transform panel. + * Refresh this canvas. */ - private void showMapEditorTransformPanel() { - JInternalFrame f = addAsFrame(new MapEditorTransformPanel(freeColClient), - true, PopupPosition.CENTERED, false); - f.setLocation(f.getX(), 50); - repaint(); + public void refresh() { + repaint(0, 0, getWidth(), getHeight()); } /** - * Display the map generator options dialog. + * Removes the given component from this canvas without + * updating the menu bar. * - * @param editable Should these options be editable. - * @return The {@code OptionGroup} as edited. - */ - public OptionGroup showMapGeneratorOptionsDialog(boolean editable) { - MapGeneratorOptionsDialog mgod - = new MapGeneratorOptionsDialog(freeColClient, frame, editable); - return showFreeColDialog(mgod, null); - } - - /** - * Display the map size dialog. - * - * @return The response returned by the dialog. + * @param comp The {@code Component} to remove. */ - public Dimension showMapSizeDialog() { - return showFreeColDialog(new MapSizeDialog(freeColClient, frame), null); - } + public void removeFromCanvas(Component comp) { + if (comp == null) return; - /** - * Displays a number of ModelMessages. - * - * @param messages The {@code ModelMessage}s to display. - */ - public void showModelMessages(List messages) { - if (messages.isEmpty()) return; - final Game game = freeColClient.getGame(); - int n = messages.size(); - String[] texts = new String[n]; - FreeColObject[] fcos = new FreeColObject[n]; - ImageIcon[] icons = new ImageIcon[n]; - Tile tile = null; - for (int i = 0; i < n; i++) { - ModelMessage m = messages.get(i); - texts[i] = Messages.message(m); - fcos[i] = game.getMessageSource(m); - icons[i] = createObjectImageIcon(game.getMessageDisplay(m)); - if (tile == null && fcos[i] instanceof Location) { - tile = ((Location)fcos[i]).getTile(); + final Rectangle updateBounds = comp.getBounds(); + final JInternalFrame jif = getInternalFrame(comp); + if (jif != null) { + notifyClose(comp, jif); + } + if (jif != null && jif != comp) { + jif.dispose(); + } else { + // Java 1.7.0 as seen on Fedora with: + // Java version: 1.7.0_40 + // Java WM version: 24.0-b56 + // crashes here deep in the java libraries. + try { + super.remove(comp); + } catch (Exception e) { + logger.log(Level.WARNING, "Java crash", e); } } - - showFreeColPanel(new InformationPanel(freeColClient, texts, fcos, - icons), - tile, true); + repaint(updateBounds.x, updateBounds.y, + updateBounds.width, updateBounds.height); } /** - * Display the monarch dialog. - * - * @param action The {@code MonarchAction} underway. - * @param template The {@code StringTemplate} describing the - * situation. - * @param monarchKey The resource key for the monarch image. - * @param handler A {@code DialogHandler} for the dialog response. + * Removes components that is only used when in game. */ - public void showMonarchDialog(MonarchAction action, - StringTemplate template, String monarchKey, - DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new MonarchDialog(freeColClient, frame, action, template, monarchKey), - null, handler)); - } + public void removeInGameComponents() { + // remove listeners, they will be added when launching the new game... + KeyListener[] keyListeners = getKeyListeners(); + for (KeyListener keyListener : keyListeners) { + removeKeyListener(keyListener); + } - /** - * Display a dialog to set a new name for something. - * - * @param template A {@code StringTemplate} for the message - * to explain the dialog. - * @param defaultName The default name. - * @param unit The {@code Unit} discovering it. - * @param handler A {@code DialogHandler} for the dialog response. - */ - public void showNamingDialog(StringTemplate template, String defaultName, - Unit unit, DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new FreeColStringInputDialog(freeColClient, frame, false, - template, defaultName, - "ok", null), - unit.getTile(), handler)); - } + MouseListener[] mouseListeners = getMouseListeners(); + for (MouseListener mouseListener : mouseListeners) { + removeMouseListener(mouseListener); + } - /** - * Display a dialog to handle a native demand to a colony. - * - * @param unit The demanding {@code Unit}. - * @param colony The {@code Colony} being demanded of. - * @param type The {@code GoodsType} demanded (null for gold). - * @param amount The amount of goods demanded. - * @param handler A {@code DialogHandler} for the dialog response. - */ - public void showNativeDemandDialog(Unit unit, Colony colony, - GoodsType type, int amount, - DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>( - new NativeDemandDialog(freeColClient, frame, unit, colony, - type, amount), - unit.getTile(), handler)); - } + MouseMotionListener[] mouseMotionListeners = getMouseMotionListeners(); + for (MouseMotionListener mouseMotionListener : mouseMotionListeners) { + removeMouseMotionListener(mouseMotionListener); + } - /** - * Displays the {@code NegotiationDialog}. - * - * @param our Our {@code FreeColGameObject} that is negotiating. - * @param other The other {@code FreeColGameObject}. - * @param agreement The current {@code DiplomaticTrade} agreement. - * @param comment An optional {@code StringTemplate} containing a - * commentary message. - * @return An updated agreement. - */ - public DiplomaticTrade showNegotiationDialog(FreeColGameObject our, - FreeColGameObject other, - DiplomaticTrade agreement, - StringTemplate comment) { - if ((!(our instanceof Unit) && !(our instanceof Colony)) - || (!(other instanceof Unit) && !(other instanceof Colony)) - || (our instanceof Colony && other instanceof Colony)) { - throw new RuntimeException("Bad DTD args: " + our + ", " + other); + for (Component c : getComponents()) { + removeFromCanvas(c); } - NegotiationDialog dtd = new NegotiationDialog(freeColClient, frame, - our, other, agreement, comment); - return showFreeColDialog(dtd, ((Location)our).getTile()); } /** - * Display the NewPanel for a given optional specification. + * Set preferred size to saved size, or to the given + * {@code Dimension} if no saved size was found. Call this + * method in the constructor of a FreeColPanel in order to + * remember its size and position. * - * @param specification The {@code Specification} to use. + * @param comp The {@code Component} to use. + * @param d The {@code Dimension} to use as default. */ - public void showNewPanel(Specification specification) { - showSubPanel(new NewPanel(freeColClient, specification), false); - } + public void restoreSavedSize(Component comp, Dimension d) { + final Dimension pref = comp.getPreferredSize(); + final Dimension sugg = (d == null) ? pref : d; + boolean save = false; - /** - * Display the parameters dialog. - * - * @return The response returned by the dialog. - */ - public Parameters showParametersDialog() { - return showFreeColDialog(new ParametersDialog(freeColClient, frame), - null); - } + Dimension size = getSavedSize(comp); + if (size == null) { + size = new Dimension(pref); + save = true; + } - /** - * Display a dialog to confirm a combat. - * - * @param attacker The attacker {@code Unit}. - * @param defender The defender. - * @param tile A {@code Tile} to make visible. - * @return True if the combat is to proceed. - */ - public boolean showPreCombatDialog(Unit attacker, - FreeColGameObject defender, - Tile tile) { - return showFreeColDialog(new PreCombatDialog(freeColClient, frame, - attacker, defender), - tile); - } + // Fix up broken/outdated saved sizes + if(size.width < sugg.width) { + size.width = sugg.width; + save = true; + } + if(size.height < sugg.height) { + size.height = sugg.height; + save = true; + } + if(size.width < pref.width) { + size.width = pref.width; + save = true; + } + if(size.height < pref.height) { + size.height = pref.height; + save = true; + } - /** - * Displays the purchase panel. - */ - public void showPurchasePanel() { - PurchasePanel panel = getExistingFreeColPanel(PurchasePanel.class); - if (panel == null) { - PurchasePanel pp = new PurchasePanel(freeColClient); - pp.update(); - showFreeColPanel(pp, null, false); + if(save) { + saveSize(comp, size); + } + + if (!pref.equals(size)) { + comp.setPreferredSize(size); } } + // Special dialogs and panels + /** - * Displays the recruit panel. + * Closes the {@link MainPanel}. */ - public void showRecruitPanel() { - RecruitPanel panel = getExistingFreeColPanel(RecruitPanel.class); - if (panel == null) { - showFreeColPanel(new RecruitPanel(freeColClient), null, false); - } + public void closeMainPanel() { + if (mainPanel != null) { + remove(mainPanel); + mainPanel = null; + } } /** - * Display the labour detail panel. + * Closes the {@code StatusPanel}. * - * @param unitType The {@code UnitType} to display. - * @param data The labour data. - * @param unitCount A map of unit distribution. - * @param colonies The list of player {@code Colony}s. + * @see #showStatusPanel */ - public void showReportLabourDetailPanel(UnitType unitType, - Map> data, - TypeCountMap unitCount, List colonies) { - ReportLabourDetailPanel details - = new ReportLabourDetailPanel(freeColClient, unitType, data, - unitCount, colonies); - details.initialize(); - showSubPanel(details, true); + public void closeStatusPanel() { + if (statusPanel.isVisible()) { + remove(statusPanel); + } } /** - * Display the river style dialog. + * Tells that a chat message was received. * - * @param styles The river styles a choice is made from. - * @return The response returned by the dialog. + * @param message The chat message. */ - public String showRiverStyleDialog(List styles) { - return showFreeColDialog( - new RiverStyleDialog(freeColClient, frame, styles), null); + public void displayChat(GUIMessage message) { + this.chatDisplay.addMessage(message); + repaint(0, 0, getWidth(), getHeight()); } /** - * Displays a dialog where the user may choose a filename. - * - * @param directory The directory containing the files in which - * the user may overwrite. - * @param defaultName Default filename for the savegame. - * @return The selected {@code File}. + * Closes all panels, changes the background and shows the main menu. */ - public File showSaveDialog(File directory, String defaultName) { - String extension = lastPart(defaultName, "."); - FileFilter[] filters = new FileFilter[] { - FreeColDataFile.getFileFilter(extension) - }; - return showFreeColDialog(new SaveDialog(freeColClient, frame, - directory, filters, - defaultName), - null); + public void mainTitle() { + // FIXME: check if the GUI object knows that we're not + // inGame. (Retrieve value of GUI::inGame.) If GUI thinks + // we're still in the game then log an error because at this + // point the GUI should have been informed. + removeInGameComponents(); + showMainPanel(); + repaint(); } /** - * Display the scale map size dialog. - * - * @return The response returned by the dialog. + * Refresh the player's table (called when a new player is added + * from PreGameInputHandler.addPlayer). */ - public Dimension showScaleMapSizeDialog() { - return showFreeColDialog(new ScaleMapSizeDialog(freeColClient, frame), - null); + public void refreshPlayersTable() { + startGamePanel.refreshPlayersTable(); } /** - * Display the select-amount dialog. + * Displays the {@code ChatPanel}. * - * @param goodsType The {@code GoodsType} to select an amount of. - * @param available The amount of goods available. - * @param defaultAmount The amount to select to start with. - * @param needToPay If true, check the player has sufficient funds. - * @return The amount selected. + * @see ChatPanel */ - public int showSelectAmountDialog(GoodsType goodsType, int available, - int defaultAmount, boolean needToPay) { - FreeColDialog fcd - = new SelectAmountDialog(freeColClient, frame, goodsType, available, - defaultAmount, needToPay); - Integer result = showFreeColDialog(fcd, null); - return (result == null) ? -1 : result; + public void showChatPanel() { + // FIXME: does it have state, or can we create a new one? + if (freeColClient.getSinglePlayer()) return; // chat with who? + showSubPanel(chatPanel, true); } /** - * Display a dialog allowing the user to select a destination for - * a given unit. - * - * @param unit The {@code Unit} to select a destination for. - * @return A destination for the unit, or null. + * Shows the {@code MainPanel}. */ - public Location showSelectDestinationDialog(Unit unit) { - return showFreeColDialog(new SelectDestinationDialog(freeColClient, frame, - unit), unit.getTile()); + public void showMainPanel() { + closeMenus(); + this.parentFrame.removeMenuBar(); + mainPanel = new MainPanel(freeColClient); + addCentered(mainPanel, JLayeredPane.DEFAULT_LAYER); + mainPanel.requestFocus(); } /** - * Display the select-tribute-amount dialog. - * - * @param question a {@code stringtemplate} describing the - * amount of tribute to demand. - * @param maximum The maximum amount available. - * @return The amount selected. + * Display the map editor transform panel. */ - public int showSelectTributeAmountDialog(StringTemplate question, - int maximum) { - FreeColDialog fcd - = new SelectTributeAmountDialog(freeColClient, frame, question, maximum); - Integer result = showFreeColDialog(fcd, null); - return (result == null) ? -1 : result; + public void showMapEditorTransformPanel() { + MapEditorTransformPanel panel + = new MapEditorTransformPanel(freeColClient); + JInternalFrame f = addAsFrame(panel, true, PopupPosition.CENTERED, + false); + f.setLocation(f.getX(), 50); + repaint(); } /** @@ -2443,7 +1520,6 @@ public int showSelectTributeAmountDialog(StringTemplate question, */ public void showServerListPanel(List serverList) { closeMenus(); - serverListPanel.initialize(serverList); showSubPanel(serverListPanel, true); } @@ -2451,34 +1527,13 @@ public void showServerListPanel(List serverList) { /** * Displays the {@code StartGamePanel}. * - * @param game The {@code Game} that is about to start. - * @param player The {@code Player} using this client. * @param singlePlayerMode True to start a single player game. * @see StartGamePanel */ - public void showStartGamePanel(Game game, Player player, - boolean singlePlayerMode) { - if (game == null) { - logger.warning("StartGamePanel requires game != null."); - } else if (player == null) { - logger.warning("StartGamePanel requires player != null."); - } else { - closeMenus(); - startGamePanel.initialize(singlePlayerMode); - showSubPanel(startGamePanel, false); - } - } - - /** - * Display the statistics panel. - * - * @param serverStats A map of server statistics key,value pairs. - * @param clientStats A map of client statistics key,value pairs. - */ - public void showStatisticsPanel(Map serverStats, - Map clientStats) { - showSubPanel(new StatisticsPanel(freeColClient, serverStats, - clientStats), true); + public void showStartGamePanel(boolean singlePlayerMode) { + closeMenus(); + startGamePanel.initialize(singlePlayerMode); + showSubPanel(startGamePanel, false); } /** @@ -2496,30 +1551,21 @@ public void showStatusPanel(String message) { addCentered(statusPanel, JLayeredPane.POPUP_LAYER); } - /** - * Display the tile panel for a given tile. - * - * @param tile The {@code Tile} to display. - */ - public void showTilePanel(Tile tile) { - if (tile == null || !tile.isExplored()) return; - showSubPanel(new TilePanel(freeColClient, tile), false); - } - /** * Shows a tile popup. * * @param tile The {@code Tile} where the popup occurred. + * @return True if the popup was shown. */ - public void showTilePopup(Tile tile) { + public boolean showTilePopup(Tile tile) { TilePopup tp = new TilePopup(freeColClient, this, tile); if (tp.hasItem()) { Point point = mapViewer.calculateTilePosition(tile, true); tp.show(this, point.x, point.y); tp.repaint(); - } else if (tile.isExplored()) { - showTilePanel(tile); + return true; } + return false; } /** @@ -2535,237 +1581,92 @@ public TradeRouteInputPanel showTradeRouteInputPanel(TradeRoute newRoute) { return panel; } - /** - * Display a panel to select a trade route for a unit. - * - * @param unit An optional {@code Unit} to select a trade route for. - */ - public void showTradeRoutePanel(Unit unit) { - showFreeColPanel(new TradeRoutePanel(freeColClient, unit), - (unit == null) ? null : unit.getTile(), true); - } - - /** - * Displays the training panel. - */ - public void showTrainPanel() { - TrainPanel panel = getExistingFreeColPanel(TrainPanel.class); - if (panel == null) { - TrainPanel tp = new TrainPanel(freeColClient); - tp.update(); - showFreeColPanel(tp, null, false); - } - } - - /** - * Display the victory dialog. - * - * @param handler A {@code DialogHandler} for the dialog response. - */ - public void showVictoryDialog(DialogHandler handler) { - SwingUtilities.invokeLater( - new DialogCallback<>(new VictoryDialog(freeColClient, frame), - null, handler)); - } - - /** - * Display the warehouse dialog for a colony. - * - * Run out of ColonyPanel, so the tile is already displayed. - * - * @param colony The {@code Colony} to display. - * @return The response returned by the dialog. - */ - public boolean showWarehouseDialog(Colony colony) { - return showFreeColDialog(new WarehouseDialog(freeColClient, frame, colony), - null); - } - - /** - * Display the production of a unit. - * - * @param unit The {@code Unit} to display. - */ - public void showWorkProductionPanel(Unit unit) { - showSubPanel(new WorkProductionPanel(freeColClient, unit), true); - } + // Override JComponent /** - * Update all panels derived from the EuropePanel. + * {@inheritDoc} */ - public void updateEuropeanSubpanels() { - RecruitPanel rp - = getExistingFreeColPanel(RecruitPanel.class); - if (rp != null) rp.update(); - PurchasePanel pp - = getExistingFreeColPanel(PurchasePanel.class); - if (pp != null) pp.update(); - TrainPanel tp - = getExistingFreeColPanel(TrainPanel.class); - if (tp != null) tp.update(); - } - - // Singleton specialist reports - - public void showReportCargoPanel() { - ReportCargoPanel r - = getExistingFreeColPanel(ReportCargoPanel.class); - if (r == null) { - showSubPanel(new ReportCargoPanel(freeColClient), true); - } - } - - public void showReportColonyPanel() { - boolean compact; - try { - compact = freeColClient.getClientOptions() - .getInteger(ClientOptions.COLONY_REPORT) - == ClientOptions.COLONY_REPORT_COMPACT; - } catch (Exception e) { - compact = false; - } - ReportPanel r = (compact) - ? getExistingFreeColPanel(ReportCompactColonyPanel.class) - : getExistingFreeColPanel(ReportClassicColonyPanel.class); - if (r == null) { - showSubPanel((compact) - ? new ReportCompactColonyPanel(freeColClient) - : new ReportClassicColonyPanel(freeColClient), - true); - } - } - - public void showReportContinentalCongressPanel() { - ReportContinentalCongressPanel - r = getExistingFreeColPanel(ReportContinentalCongressPanel.class); - if (r == null) { - showSubPanel(new ReportContinentalCongressPanel(freeColClient), - true); - } - } - - public void showReportEducationPanel() { - ReportEducationPanel r - = getExistingFreeColPanel(ReportEducationPanel.class); - if (r == null) { - showSubPanel(new ReportEducationPanel(freeColClient), true); - } - } - - public void showReportExplorationPanel() { - ReportExplorationPanel r - = getExistingFreeColPanel(ReportExplorationPanel.class); - if (r == null) { - showSubPanel(new ReportExplorationPanel(freeColClient), true); - } - } - - public void showReportForeignAffairPanel() { - ReportForeignAffairPanel r - = getExistingFreeColPanel(ReportForeignAffairPanel.class); - if (r == null) { - showSubPanel(new ReportForeignAffairPanel(freeColClient), true); - } - } - - public void showReportHistoryPanel() { - ReportHistoryPanel r - = getExistingFreeColPanel(ReportHistoryPanel.class); - if (r == null) { - showSubPanel(new ReportHistoryPanel(freeColClient), true); - } - } - - public void showReportIndianPanel() { - ReportIndianPanel r - = getExistingFreeColPanel(ReportIndianPanel.class); - if (r == null) { - showSubPanel(new ReportIndianPanel(freeColClient), true); + @Override + public void paintComponent(Graphics g) { + Dimension newSize = checkResize(); + if (newSize != null) { + updateMapControlsInCanvas(); + mapViewer.changeSize(newSize); } - } + boolean hasMap = this.freeColClient != null + && this.freeColClient.getGame() != null + && this.freeColClient.getGame().getMap() != null; + Graphics2D g2d = (Graphics2D) g; + Dimension size = getSize(); - public void showReportLabourPanel() { - ReportLabourPanel r - = getExistingFreeColPanel(ReportLabourPanel.class); - if (r == null) { - showSubPanel(new ReportLabourPanel(freeColClient), true); - } - } + if (freeColClient.isMapEditor()) { + if (hasMap) { + mapViewer.displayMap(g2d); + } else { + g2d.setColor(Color.BLACK); + g2d.fillRect(0, 0, size.width, size.height); + } - public void showReportMilitaryPanel() { - ReportMilitaryPanel r - = getExistingFreeColPanel(ReportMilitaryPanel.class); - if (r == null) { - showSubPanel(new ReportMilitaryPanel(freeColClient), true); - } - } + } else if (freeColClient.isInGame() && hasMap) { + // draw the map + mapViewer.displayMap(g2d); - public void showReportNavalPanel() { - ReportNavalPanel r - = getExistingFreeColPanel(ReportNavalPanel.class); - if (r == null) { - showSubPanel(new ReportNavalPanel(freeColClient), true); - } - } + // toggle grey layer if needed + if (freeColClient.currentPlayerIsMyPlayer()) { + if (greyLayer.getParent() != null) { + removeFromCanvas(greyLayer); + } + } else { + greyLayer.setBounds(0, 0, size.width, size.height); + greyLayer.setPlayer(freeColClient.getGame().getCurrentPlayer()); + if (greyLayer.getParent() == null) { + addToCanvas(greyLayer, JLayeredPane.DRAG_LAYER); + } + } - public void showReportProductionPanel() { - ReportProductionPanel r - = getExistingFreeColPanel(ReportProductionPanel.class); - if (r == null) { - showSubPanel(new ReportProductionPanel(freeColClient), true); - } - } + // draw the chat + this.chatDisplay.display(g2d, this.imageLibrary, size); - public void showReportReligiousPanel() { - ReportReligiousPanel r - = getExistingFreeColPanel(ReportReligiousPanel.class); - if (r == null) { - showSubPanel(new ReportReligiousPanel(freeColClient), true); + } else { /* main menu */ + // Get the background without scaling, to avoid wasting + // memory needlessly keeping an unbounded number of rescaled + // versions of the largest image in FreeCol, forever. + final Image bgImage = ImageLibrary.getCanvasBackgroundImage(); + if (bgImage != null) { + // Draw background image with scaling. + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2d.drawImage(bgImage, 0, 0, size.width, size.height, this); + String versionStr = "v. " + FreeCol.getVersion(); + Font oldFont = g2d.getFont(); + Color oldColor = g2d.getColor(); + Font newFont = oldFont.deriveFont(Font.BOLD); + TextLayout layout = new TextLayout(versionStr, newFont, + g2d.getFontRenderContext()); + Rectangle2D bounds = layout.getBounds(); + float x = size.width - (float) bounds.getWidth() - 5; + float y = size.height - (float) bounds.getHeight(); + g2d.setColor(Color.white); + layout.draw(g2d, x, y); + g2d.setFont(oldFont); + g2d.setColor(oldColor); + } else { + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, size.width, size.height); + logger.warning("Unable to load the canvas background"); + } } } - public void showReportRequirementsPanel() { - ReportRequirementsPanel r - = getExistingFreeColPanel(ReportRequirementsPanel.class); - if (r == null) { - showSubPanel(new ReportRequirementsPanel(freeColClient), true); - } - } - public void showReportTradePanel() { - ReportTradePanel r - = getExistingFreeColPanel(ReportTradePanel.class); - if (r == null) { - showSubPanel(new ReportTradePanel(freeColClient), true); - } - } + // Override Container /** - * Show the turn report. - * - * @param messages The {@code ModelMessage}s to show. + * {@inheritDoc} */ - public void showReportTurnPanel(List messages) { - ReportTurnPanel r = getExistingFreeColPanel(ReportTurnPanel.class); - if (r == null) { - showSubPanel(new ReportTurnPanel(freeColClient, messages), true); - } else { - r.setMessages(messages); - } - } - - /** - * Shows the given video Component. - * - * @param vp The video Component. - * @param ml A MouseListener for stopping the video. - * @param kl A KeyListener for stopping the video. - */ - public void showVideoComponent(final Component vp, - final MouseListener ml, - final KeyListener kl) { - addMouseListener(ml); - addKeyListener(kl); - addCentered(vp, JLayeredPane.PALETTE_LAYER); + @Override + public void remove(Component comp) { + removeFromCanvas(comp); + updateMenuBar(); } } diff --git a/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java b/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java index 2db41b949f..c0c1d13398 100644 --- a/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java +++ b/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java @@ -145,7 +145,7 @@ public void mousePressed(MouseEvent e) { Tile tile = canvas.convertToMapTile(e.getX(), e.getY()); if (tile != null) { if (tile.getIndianSettlement() != null) { - canvas.showEditSettlementDialog(tile.getIndianSettlement()); + getGUI().showEditSettlementDialog(tile.getIndianSettlement()); } } } diff --git a/src/net/sf/freecol/client/gui/CanvasMouseMotionListener.java b/src/net/sf/freecol/client/gui/CanvasMouseMotionListener.java index 84d2e13655..78d68083fd 100644 --- a/src/net/sf/freecol/client/gui/CanvasMouseMotionListener.java +++ b/src/net/sf/freecol/client/gui/CanvasMouseMotionListener.java @@ -69,8 +69,8 @@ public void mouseMoved(MouseEvent me) { @Override public void mouseDragged(MouseEvent me) { // getButton does not work here, TODO: find out why - if ((me.getModifiers() & MouseEvent.BUTTON1_MASK) - != MouseEvent.BUTTON1_MASK) return; + if ((me.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) + != MouseEvent.BUTTON1_DOWN_MASK) return; performDragScrollIfActive(me); getGUI().updateGoto(me.getX(), me.getY(), true); diff --git a/src/net/sf/freecol/client/gui/ChatDisplay.java b/src/net/sf/freecol/client/gui/ChatDisplay.java index 3249d3062c..52ecee91d8 100644 --- a/src/net/sf/freecol/client/gui/ChatDisplay.java +++ b/src/net/sf/freecol/client/gui/ChatDisplay.java @@ -23,6 +23,7 @@ import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; +import java.util.List; import java.util.ArrayList; import java.util.Date; @@ -37,13 +38,24 @@ public class ChatDisplay { /** The number of messages getting remembered. */ private static final int MESSAGE_COUNT = 3; + /** Left margin for the text. */ + private static final int LEFT_MARGIN = 40; + + /** Top margin for the text. */ + private static final int TOP_MARGIN = 300; + /** The amount of time before a message gets deleted (in milliseconds). */ private static final int MESSAGE_AGE = 30000; - private final ArrayList messages; + /** The messages to display. */ + private final List messages; + - ChatDisplay() { - messages = new ArrayList<>(MESSAGE_COUNT); + /** + * Create the chat display/ container. + */ + public ChatDisplay() { + this.messages = new ArrayList<>(MESSAGE_COUNT); } /** @@ -53,34 +65,33 @@ public class ChatDisplay { * @param message The message to add. */ public synchronized void addMessage(GUIMessage message) { - if (getMessageCount() == MESSAGE_COUNT) { - messages.remove(0); + if (this.messages.size() >= MESSAGE_COUNT) { + this.messages.remove(0); } - messages.add(message); + this.messages.add(message); } /** - * Gets the message at position 'index'. The message at position 0 - * is the oldest message and is most likely to be removed during - * the next call of removeOldMessages(). The higher the index of - * a message, the more recently it was added. + * Removes all the message that are older than MESSAGE_AGE. * - * @param index The index of the message to return. - * @return The message at position 'index'. - */ - private GUIMessage getMessage(int index) { - return messages.get(index); - } - - /** - * Gets the amount of message that are currently being displayed - * on this GUI. + * This can be useful to see if it is necessary to refresh the screen. * - * @return The amount of message that are currently being - * displayed on this GUI. + * @return True if all messages are gone. */ - private int getMessageCount() { - return messages.size(); + private boolean removeOldMessages() { + long currentTime = new Date().getTime(); + boolean result = false; + + int i = 0; + while (i < this.messages.size()) { + long creationTime = this.messages.get(i).getCreationTime(); + if ((currentTime - creationTime) >= MESSAGE_AGE) { + this.messages.remove(i); + } else { + i++; + } + } + return this.messages.isEmpty(); } /** @@ -90,63 +101,38 @@ private int getMessageCount() { * @param lib The imageLibrary to use. * @param size The size of the space for displaying in. */ - public synchronized void display(Graphics2D g, ImageLibrary lib, Dimension size) { - if (getMessageCount() > 0) { - // Don't edit the list of messages while I'm drawing them. - Font font = FontLibrary.createFont(FontLibrary.FontType.NORMAL, - FontLibrary.FontSize.TINY, lib.getScaleFactor()); - GUIMessage message = getMessage(0); - Image si = lib.getStringImage(g, message.getMessage(), - message.getColor(), font); - int yy = size.height - 300 - getMessageCount() * si.getHeight(null); - int xx = 40; - - for (int i = 0; i < getMessageCount(); i++) { - message = getMessage(i); - g.drawImage(lib.getStringImage(g, message.getMessage(), - message.getColor(), font), - xx, yy, null); - yy += si.getHeight(null); - } - Image decoration = ImageLibrary - .getUnscaledImage("image.menuborder.shadow.s"); - int width = decoration.getWidth(null); - for (int index = 0; index < size.width; index += width) { - g.drawImage(decoration, index, 0, null); + public synchronized void display(Graphics2D g, ImageLibrary lib, + Dimension size) { + // Return quickly if there are no messages, which is always + // true in single player games. + if (this.messages.isEmpty() || removeOldMessages()) return; + + final Font font = FontLibrary.createFont(FontLibrary.FontType.NORMAL, + FontLibrary.FontSize.TINY, lib.getScaleFactor()); + int yy = -1; + final int xx = LEFT_MARGIN; + for (GUIMessage m : this.messages) { + Image si = lib.getStringImage(g, m.getMessage(), + m.getColor(), font); + if (yy < 0) { + yy = size.height - TOP_MARGIN + - this.messages.size() * si.getHeight(null); } - decoration = ImageLibrary - .getUnscaledImage("image.menuborder.shadow.sw"); - g.drawImage(decoration, 0, 0, null); - decoration = ImageLibrary - .getUnscaledImage("image.menuborder.shadow.se"); - g.drawImage(decoration, size.width - decoration.getWidth(null), - 0, null); + g.drawImage(si, xx, yy, null); + yy += si.getHeight(null); } - } - - /** - * Removes all the message that are older than MESSAGE_AGE. - * - * This can be useful to see if it is necessary to refresh the - * screen. - * - * @return True if at least one message has been removed, - */ - public synchronized boolean removeOldMessages() { - long currentTime = new Date().getTime(); - boolean result = false; - - int i = 0; - while (i < getMessageCount()) { - long creationTime = getMessage(i).getCreationTime(); - if ((currentTime - creationTime) >= MESSAGE_AGE) { - result = true; - messages.remove(i); - } else { - i++; - } + Image decoration = ImageLibrary + .getUnscaledImage("image.menuborder.shadow.s"); + int width = decoration.getWidth(null); + for (int index = 0; index < size.width; index += width) { + g.drawImage(decoration, index, 0, null); } - return result; + decoration = ImageLibrary + .getUnscaledImage("image.menuborder.shadow.sw"); + g.drawImage(decoration, 0, 0, null); + decoration = ImageLibrary + .getUnscaledImage("image.menuborder.shadow.se"); + g.drawImage(decoration, size.width - decoration.getWidth(null), + 0, null); } - } diff --git a/src/net/sf/freecol/client/gui/FreeColFrame.java b/src/net/sf/freecol/client/gui/FreeColFrame.java index 18087c2132..677be75472 100644 --- a/src/net/sf/freecol/client/gui/FreeColFrame.java +++ b/src/net/sf/freecol/client/gui/FreeColFrame.java @@ -36,9 +36,6 @@ import net.sf.freecol.FreeCol; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.menu.FreeColMenuBar; -import net.sf.freecol.client.gui.menu.InGameMenuBar; -import net.sf.freecol.client.gui.menu.MapEditorMenuBar; -import net.sf.freecol.client.gui.menu.MenuMouseMotionListener; /** @@ -51,9 +48,6 @@ public class FreeColFrame extends JFrame { /** The FreeCol client controlling the frame. */ protected final FreeColClient freeColClient; - /** The Canvas contained inside the frame. */ - protected final Canvas canvas; - /** * Create a new main frame. @@ -61,19 +55,16 @@ public class FreeColFrame extends JFrame { * @param freeColClient The enclosing {@code FreeColClient}. * @param gd The {@code GraphicsDevice} to use. * @param menuBar The menu bar to add to the frame. - * @param canvas The Canvas to add to the frame. * @param windowed If the frame should be windowed. * @param bounds The optional size of the windowed frame. */ public FreeColFrame(FreeColClient freeColClient, GraphicsDevice gd, - JMenuBar menuBar, Canvas canvas, boolean windowed, - Rectangle bounds) { + JMenuBar menuBar, boolean windowed, Rectangle bounds) { super(getFrameName(), gd.getDefaultConfiguration()); this.freeColClient = freeColClient; - this.canvas = canvas; setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); - if(windowed) { + if (windowed) { setResizable(true); } else { setUndecorated(true); @@ -83,7 +74,6 @@ public FreeColFrame(FreeColClient freeColClient, GraphicsDevice gd, addWindowListener(windowed ? new WindowedFrameListener(freeColClient) : new FullScreenFrameListener(freeColClient, this)); - setCanvas(); setIconImage(ImageLibrary.getUnscaledImage("image.miscicon.FrameIcon")); pack(); // necessary for getInsets @@ -123,17 +113,11 @@ public void exitFullScreen() { gd.setFullScreenWindow(null); } - public void setInGameMenuBar() { - setJMenuBar(new InGameMenuBar(freeColClient, - new MenuMouseMotionListener(freeColClient, canvas))); + public void setMenuBar(FreeColMenuBar bar) { + setJMenuBar(bar); validate(); } - - public void setMapEditorMenuBar() { - setJMenuBar(new MapEditorMenuBar(freeColClient, - new MenuMouseMotionListener(freeColClient, canvas))); - } - + public void removeMenuBar() { setJMenuBar(null); validate(); @@ -161,23 +145,4 @@ public void updateMenuBar() { private static String getFrameName() { return "FreeCol " + FreeCol.getVersion(); } - - - /** - * Set the canvas for this frame. - */ - private void setCanvas() { - // This crashes deep in the Java libraries when changing full screen - // mode during the opening video - // Java version: 1.7.0_45 - // Java WM name: OpenJDK 64-Bit Server VM - // Java WM version: 24.45-b08 - // arch linux, reported by Lone Wolf - try { - getContentPane().add(canvas); - } catch (Exception e) { - logger.log(Level.WARNING, "Java crash", e); - } - } - } diff --git a/src/net/sf/freecol/client/gui/GUI.java b/src/net/sf/freecol/client/gui/GUI.java index fc346e5c34..25b3694753 100644 --- a/src/net/sf/freecol/client/gui/GUI.java +++ b/src/net/sf/freecol/client/gui/GUI.java @@ -1262,7 +1262,7 @@ public boolean isWindowed() { // Initialization and teardown /** - * Change the windowed mode. + * Change the windowed mode (really a toggle). */ public void changeWindowedMode() {} @@ -1924,6 +1924,13 @@ public void removeComponent(Component component) {} */ public void removeDialog(FreeColDialog fcd) {} + /** + * Remove a trade route panel and associated input. + * + * @param panel The {@code FreeColPanel} to remove. + */ + public void removeTradeRoutePanel(FreeColPanel panel) {} + /** * Set dialog preferred size to saved size or to the given * {@code Dimension} if no saved size was found. @@ -2060,6 +2067,16 @@ public boolean showEditOptionDialog(Option option) { return false; } + /** + * Show a dialog for editing a settlmeent. + * + * @param settlement The {@code IndianSettlement} to edit. + * @return The settlement post-edit. + */ + public IndianSettlement showEditSettlementDialog(IndianSettlement settlement) { + return null; + } + /** * Show a dialog to handle emigration. * diff --git a/src/net/sf/freecol/client/gui/SplashScreen.java b/src/net/sf/freecol/client/gui/SplashScreen.java new file mode 100644 index 0000000000..066ac133d4 --- /dev/null +++ b/src/net/sf/freecol/client/gui/SplashScreen.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2002-2019 The FreeCol Team + * + * This file is part of FreeCol. + * + * FreeCol is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * FreeCol is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FreeCol. If not, see . + */ + +package net.sf.freecol.client.gui; + +import java.awt.DisplayMode; +import java.awt.GraphicsDevice; +import java.awt.Point; +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JWindow; + + +/** + * Class to contain the splash screen. + */ +public final class SplashScreen extends JWindow { + + /** + * Initialize the splash screen. + * + * @param gd The {@code GraphicsDevice} to display on. + * @param splashStream An {@code InputStream} to read content from. + */ + public SplashScreen(GraphicsDevice gd, InputStream splashStream) + throws IOException { + super(gd.getDefaultConfiguration()); + + BufferedImage im = ImageIO.read(splashStream); + this.getContentPane().add(new JLabel(new ImageIcon(im))); + this.pack(); + this.setVisible(false); + + Point start = this.getLocation(); + DisplayMode dm = gd.getDisplayMode(); + int x = start.x + dm.getWidth()/2 - this.getWidth() / 2; + int y = start.y + dm.getHeight()/2 - this.getHeight() / 2; + this.setLocation(x, y); + } +} diff --git a/src/net/sf/freecol/client/gui/SwingGUI.java b/src/net/sf/freecol/client/gui/SwingGUI.java index 5e9754d71e..ef6770c938 100644 --- a/src/net/sf/freecol/client/gui/SwingGUI.java +++ b/src/net/sf/freecol/client/gui/SwingGUI.java @@ -21,21 +21,12 @@ import java.awt.Component; import java.awt.Dimension; -import java.awt.DisplayMode; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.HeadlessException; -import java.awt.MouseInfo; import java.awt.Point; import java.awt.Rectangle; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.io.File; @@ -44,33 +35,27 @@ import java.util.Locale; import java.util.logging.Level; -import javax.imageio.ImageIO; import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JWindow; -import javax.swing.Timer; import net.sf.freecol.FreeCol; import net.sf.freecol.client.ClientOptions; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.control.MapTransform; -import net.sf.freecol.client.gui.ImageLibrary; import net.sf.freecol.client.gui.animation.Animations; -import net.sf.freecol.client.gui.dialog.CaptureGoodsDialog; +// Special panels and dialogs import net.sf.freecol.client.gui.dialog.FreeColDialog; import net.sf.freecol.client.gui.dialog.Parameters; import net.sf.freecol.client.gui.panel.BuildQueuePanel; import net.sf.freecol.client.gui.panel.ColonyPanel; import net.sf.freecol.client.gui.panel.ColorChooserPanel; -import net.sf.freecol.client.gui.panel.CornerMapControls; +import net.sf.freecol.client.gui.panel.FreeColPanel; import net.sf.freecol.client.gui.panel.report.LabourData.UnitData; import net.sf.freecol.client.gui.panel.InformationPanel; -import net.sf.freecol.client.gui.panel.MapControls; import net.sf.freecol.client.gui.panel.TradeRouteInputPanel; + import net.sf.freecol.client.gui.panel.Utility; import net.sf.freecol.client.gui.plaf.FreeColLookAndFeel; -import net.sf.freecol.client.gui.video.VideoComponent; -import net.sf.freecol.client.gui.video.VideoListener; + import net.sf.freecol.common.FreeColException; import net.sf.freecol.common.i18n.Messages; import net.sf.freecol.common.metaserver.ServerInfo; @@ -108,16 +93,18 @@ import net.sf.freecol.common.option.LanguageOption.Language; import net.sf.freecol.common.option.Option; import net.sf.freecol.common.option.OptionGroup; -import net.sf.freecol.common.resources.Video; -import net.sf.freecol.common.util.Introspector; import static net.sf.freecol.common.util.StringUtils.*; - +import net.sf.freecol.common.util.Utils; /** * A wrapper providing functionality for the overall GUI using Java Swing. */ public class SwingGUI extends GUI { + /** Number of pixels that must be moved before a goto is enabled. */ + private static final int DRAG_THRESHOLD = 16; + + /** The graphics device to display to. */ private final GraphicsDevice graphicsDevice; /** @@ -136,9 +123,14 @@ public class SwingGUI extends GUI { /** The canvas that implements much of the functionality. */ private Canvas canvas; - private MapControls mapControls; + /** The widgets wrapper that handles specific panels and dialogs. */ + private Widgets widgets; + + /** Where the map was drag-clicked. */ + private Point dragPoint; - private JWindow splash; + /** The splash screen. */ + private SplashScreen splash; /** @@ -149,8 +141,18 @@ public class SwingGUI extends GUI { */ public SwingGUI(FreeColClient freeColClient, float scaleFactor) { super(freeColClient, scaleFactor); - - this.graphicsDevice = getGoodGraphicsDevice(); + + this.graphicsDevice = Utils.getGoodGraphicsDevice(); + if (this.graphicsDevice == null) { + FreeCol.fatal(logger, "Could not find a GraphicsDevice!"); + } + this.tileViewer = new TileViewer(freeColClient); + // Defer remaining initializations, possibly to startGUI + this.mapViewer = null; + this.canvas = null; + this.widgets = null; + this.dragPoint = null; + this.splash = null; logger.info("GUI constructed using scale factor " + scaleFactor); } @@ -158,24 +160,22 @@ public SwingGUI(FreeColClient freeColClient, float scaleFactor) { // Internals /** - * Get a good screen device for starting FreeCol. + * Gets the point at which the map was clicked for a drag. * - * @return A screen device, or null if none available - * (as in headless mode). + * @return The Point where the mouse was initially clicked. */ - private static GraphicsDevice getGoodGraphicsDevice() { - try { - return MouseInfo.getPointerInfo().getDevice(); - } catch (HeadlessException he) {} - - try { - final GraphicsEnvironment lge - = GraphicsEnvironment.getLocalGraphicsEnvironment(); - return lge.getDefaultScreenDevice(); - } catch (HeadlessException he) {} + private Point getDragPoint() { + return this.dragPoint; + } - FreeCol.fatal(logger, "Could not find a GraphicsDevice!"); - return null; + /** + * Sets the point at which the map was clicked for a drag. + * + * @param x The mouse x position. + * @param y The mouse y position. + */ + private void setDragPoint(int x, int y) { + this.dragPoint = new Point(x, y); } /** @@ -272,6 +272,21 @@ private void updateUnitPath() { setUnitPath(path); } + /** + * Is mouse movement differnce above the drag threshold? + * + * @param x The new mouse x position. + * @param y The new mouse y position. + * @return True if the mouse has been dragged. + */ + public boolean isDrag(int x, int y) { + final Point drag = getDragPoint(); + if (drag == null) return false; + int deltaX = Math.abs(x - drag.x); + int deltaY = Math.abs(y - drag.y); + return deltaX >= DRAG_THRESHOLD || deltaY >= DRAG_THRESHOLD; + } + /** * Update the current goto to a given tile. * @@ -281,8 +296,20 @@ private void updateGotoTile(Tile tile) { final Unit unit = getActiveUnit(); if (tile == null || unit == null) { clearGotoPath(); - } else { - canvas.changeGoto(unit, tile); + } else if (canvas.isGotoStarted()) { + // Do nothing if the tile has not changed. + PathNode oldPath = mapViewer.getGotoPath(); + Tile lastTile = (oldPath == null) ? null + : oldPath.getLastNode().getTile(); + if (lastTile == tile) return; + + // Do not show a path if it will be invalid, avoiding calling + // the expensive path finder if possible. + PathNode newPath = (unit.getTile() == tile + || !tile.isExplored() + || !unit.getSimpleMoveType(tile).isLegal()) ? null + : unit.findPath(tile); + mapViewer.changeGotoPath(newPath); } } @@ -323,7 +350,7 @@ public boolean isWindowed() { */ @Override public void changeWindowedMode() { - canvas.changeWindowedMode(); + canvas.toggleFrame(); } /** @@ -331,21 +358,14 @@ public void changeWindowedMode() { */ @Override public void displaySplashScreen(final InputStream splashStream) { - splash = null; - if (splashStream == null) return; - try { - BufferedImage im = ImageIO.read(splashStream); - splash = new JWindow(graphicsDevice.getDefaultConfiguration()); - splash.getContentPane().add(new JLabel(new ImageIcon(im))); - splash.pack(); - Point start = splash.getLocation(); - DisplayMode dm = graphicsDevice.getDisplayMode(); - splash.setLocation(start.x + dm.getWidth()/2 - splash.getWidth() / 2, - start.y + dm.getHeight()/2 - splash.getHeight() / 2); - splash.setVisible(true); - } catch (Exception e) { - logger.log(Level.WARNING, "Splash fail", e); - splash = null; + if (splashStream != null) { + try { + this.splash = new SplashScreen(this.graphicsDevice, + splashStream); + } catch (Exception e) { + logger.log(Level.WARNING, "Splash screen failure", e); + } + this.splash.setVisible(true); } } @@ -354,10 +374,9 @@ public void displaySplashScreen(final InputStream splashStream) { */ @Override public void hideSplashScreen() { - if (splash != null) { - splash.setVisible(false); - splash.dispose(); - splash = null; + if (this.splash != null) { + this.splash.setVisible(false); + this.splash = null; } } @@ -389,10 +408,9 @@ public void quit() { */ @Override public void reconnect(Unit active, Tile tile) { - canvas.setupMouseListeners(); requestFocusInWindow(); canvas.initializeInGame(); - enableMapControls(getClientOptions() + canvas.enableMapControls(getClientOptions() .getBoolean(ClientOptions.DISPLAY_MAP_CONTROLS)); closeMenus(); clearGotoPath(); @@ -412,6 +430,8 @@ public void reconnect(Unit active, Tile tile) { */ @Override public void removeInGameComponents() { + changeActiveUnit(null); + changeSelectedTile(null, false); canvas.removeInGameComponents(); } @@ -420,90 +440,12 @@ public void removeInGameComponents() { */ @Override public void showOpeningVideo(final String userMsg) { - canvas.closeMenus(); - final Video video = ImageLibrary.getVideo("video.opening"); - boolean muteAudio = !getSoundController().canPlaySound(); - final VideoComponent vp = new VideoComponent(video, muteAudio); - - final class AbortListener implements ActionListener, KeyListener, - MouseListener, VideoListener { - - private Timer t = null; - - @Override - public void keyPressed(KeyEvent e) { - } - - @Override - public void keyReleased(KeyEvent e1) { - execute(); - } - - @Override - public void keyTyped(KeyEvent e2) { - } - - @Override - public void mouseClicked(MouseEvent e3) { - execute(); - } - - @Override - public void mouseEntered(MouseEvent e4) { - } - - @Override - public void mouseExited(MouseEvent e5) { - } - - @Override - public void mousePressed(MouseEvent e6) { - } - - @Override - public void mouseReleased(MouseEvent e7) { - } - - @Override - public void stopped() { - execute(); - } - - @Override - public void actionPerformed(ActionEvent ae8) { - execute(); - } - - private void setTimer(Timer t1) { - this.t = t1; - } - - private void execute() { - canvas.removeKeyListener(this); - canvas.removeMouseListener(this); - vp.removeMouseListener(this); - //vp.removeVideoListener(this); - vp.stop(); - canvas.remove(vp); - if (t != null) { - t.stop(); - } - playSound("sound.intro.general"); - showMainPanel(userMsg); - } - } - AbortListener l = new AbortListener(); - vp.addMouseListener(l); - //vp.addVideoListener(l); - canvas.showVideoComponent(vp, l, l); - vp.play(); - // Cortado applet is failing to quit when finished, make sure it - // eventually gets kicked. Change the magic number if we - // change the opening video length. - Timer t2 = new Timer(80000, l); - l.setTimer(t2); - t2.setRepeats(false); - t2.start(); + canvas.playVideo("video.opening", + !getSoundController().canPlaySound(), + () -> { + playSound("sound.intro.general"); + showMainPanel(userMsg); + }); } /** @@ -513,9 +455,10 @@ private void execute() { public void startGUI(final Dimension desiredWindowSize) { final ClientOptions opts = getClientOptions(); this.mapViewer = new MapViewer(getFreeColClient()); - this.canvas = new Canvas(getFreeColClient(), graphicsDevice, this, + this.canvas = new Canvas(getFreeColClient(), graphicsDevice, desiredWindowSize, this.mapViewer); - this.tileViewer = new TileViewer(getFreeColClient()); + this.widgets = new Widgets(getFreeColClient(), + mapViewer.getImageLibrary(), this.canvas); // Now that there is a canvas, prepare for language changes. opts.getOption(ClientOptions.LANGUAGE, LanguageOption.class) @@ -536,7 +479,6 @@ public void startGUI(final Dimension desiredWindowSize) { // No longer doing anything special for pmoffscreen et al as // changing these in-game does not change the now initialized // graphics pipeline. - logger.info("GUI started."); } @@ -547,6 +489,7 @@ public void startGUI(final Dimension desiredWindowSize) { public void startMapEditorGUI() { resetMapZoom(); // Reset zoom to the default canvas.startMapEditorGUI(); + canvas.showMapEditorTransformPanel(); } @@ -642,7 +585,7 @@ public Point getAnimationTilePosition(Tile tile) { */ @Override public boolean confirm(String textKey, String okKey, String cancelKey) { - return canvas.showConfirmDialog(null, StringTemplate.key(textKey), + return widgets.showConfirmDialog(null, StringTemplate.key(textKey), null, okKey, cancelKey); } @@ -652,7 +595,7 @@ public boolean confirm(String textKey, String okKey, String cancelKey) { @Override public boolean confirm(Tile tile, StringTemplate tmpl, ImageIcon icon, String okKey, String cancelKey) { - return canvas.showConfirmDialog(tile, tmpl, icon, okKey, cancelKey); + return widgets.showConfirmDialog(tile, tmpl, icon, okKey, cancelKey); } /** @@ -661,7 +604,7 @@ public boolean confirm(Tile tile, StringTemplate tmpl, ImageIcon icon, @Override protected T getChoice(Tile tile, StringTemplate tmpl, ImageIcon icon, String cancelKey, List> choices) { - return canvas.showChoiceDialog(tile, tmpl, icon, cancelKey, choices); + return widgets.showChoiceDialog(tile, tmpl, icon, cancelKey, choices); } /** @@ -670,8 +613,8 @@ protected T getChoice(Tile tile, StringTemplate tmpl, ImageIcon icon, @Override public String getInput(Tile tile, StringTemplate tmpl, String defaultValue, String okKey, String cancelKey) { - return canvas.showInputDialog(tile, tmpl, defaultValue, - okKey, cancelKey); + return widgets.showInputDialog(tile, tmpl, defaultValue, + okKey, cancelKey); } @@ -864,7 +807,7 @@ public void traverseGotoPath() { */ @Override public void updateGoto(int x, int y, boolean start) { - if (start && canvas.isDrag(x, y)) { + if (start && isDrag(x, y)) { canvas.startGoto(); } if (canvas.isGotoStarted()) { @@ -878,19 +821,19 @@ public void updateGoto(int x, int y, boolean start) { @Override public void prepareDrag(int x, int y) { if (canvas.isGotoStarted()) canvas.stopGoto(); - canvas.setDragPoint(x, y); + setDragPoint(x, y); canvas.requestFocus(); } - // MapControls handling + // MapControls is delegated to Canvas /** * {@inheritDoc} */ @Override public boolean canZoomInMapControls() { - return mapControls != null && mapControls.canZoomInMapControls(); + return canvas.canZoomInMapControls(); } /** @@ -898,7 +841,7 @@ public boolean canZoomInMapControls() { */ @Override public boolean canZoomOutMapControls() { - return mapControls != null && mapControls.canZoomOutMapControls(); + return canvas.canZoomOutMapControls(); } /** @@ -906,26 +849,7 @@ public boolean canZoomOutMapControls() { */ @Override public void enableMapControls(boolean enable) { - // Always instantiate in game. - if (enable && mapControls == null) { - String className = getClientOptions().getString(ClientOptions.MAP_CONTROLS); - final String panelName = "net.sf.freecol.client.gui.panel." - + lastPart(className, "."); - try { - mapControls = (MapControls)Introspector.instantiate(panelName, - new Class[] { FreeColClient.class }, - new Object[] { getFreeColClient() }); - mapControls.addToComponent(canvas); - mapControls.update(); - logger.info("Instantiated " + panelName); - } catch (Introspector.IntrospectorException ie) { - logger.log(Level.WARNING, "Failed in make map controls for: " - + panelName, ie); - } - } else if (!enable && mapControls != null) { - mapControls.removeFromComponent(canvas); - mapControls = null; - } + canvas.enableMapControls(enable); } /** @@ -933,8 +857,7 @@ public void enableMapControls(boolean enable) { */ @Override public void miniMapToggleViewControls() { - if (mapControls == null) return; - mapControls.toggleView(); + canvas.miniMapToggleViewControls(); } /** @@ -942,8 +865,7 @@ public void miniMapToggleViewControls() { */ @Override public void miniMapToggleFogOfWarControls() { - if (mapControls == null) return; - mapControls.toggleFogOfWar(); + canvas.miniMapToggleFogOfWarControls(); } /** @@ -951,7 +873,7 @@ public void miniMapToggleFogOfWarControls() { */ @Override public void updateMapControls() { - if (mapControls != null) mapControls.update(); + canvas.updateMapControls(); } /** @@ -959,9 +881,7 @@ public void updateMapControls() { */ @Override public void updateMapControlsInCanvas() { - if (mapControls == null) return; - mapControls.removeFromComponent(canvas); - mapControls.addToComponent(canvas); + canvas.updateMapControlsInCanvas(); } /** @@ -969,8 +889,7 @@ public void updateMapControlsInCanvas() { */ @Override public void zoomInMapControls() { - if (mapControls == null) return; - mapControls.zoomIn(); + canvas.zoomInMapControls(); } /** @@ -978,8 +897,7 @@ public void zoomInMapControls() { */ @Override public void zoomOutMapControls() { - if (mapControls == null) return; - mapControls.zoomOut(); + canvas.zoomOutMapControls(); } @@ -1204,7 +1122,7 @@ public void zoomOutMap() { public void clickAt(int count, int x, int y) { // This could be a drag, which would have already been processed // in @see CanvasMouseListener#mouseReleased - if (count == 1 && canvas.isDrag(x, y)) return; + if (count == 1 && isDrag(x, y)) return; final Tile tile = canvas.convertToMapTile(x, y); if (tile == null) return; @@ -1273,7 +1191,7 @@ public void closeStatusPanel() { */ @Override public List confirmDeclaration() { - return canvas.showConfirmDeclarationDialog(); + return widgets.showConfirmDeclarationDialog(); } /** @@ -1293,22 +1211,22 @@ public void displayChat(Player player, String message, public void displayObject(FreeColObject fco) { // TODO: Improve OO. if (fco instanceof Colony) { - canvas.showColonyPanel((Colony)fco, null); + widgets.showColonyPanel((Colony)fco, null); } else if (fco instanceof Europe) { - canvas.showEuropePanel(); + widgets.showEuropePanel(); } else if (fco instanceof IndianSettlement) { - canvas.showIndianSettlementPanel((IndianSettlement)fco); + widgets.showIndianSettlementPanel((IndianSettlement)fco); } else if (fco instanceof Tile) { setFocus((Tile)fco); } else if (fco instanceof Unit) { Location loc = ((Unit)fco).up(); if (loc instanceof Colony) { - canvas.showColonyPanel((Colony)loc, (Unit)fco); + widgets.showColonyPanel((Colony)loc, (Unit)fco); } else { displayObject((FreeColObject)loc); } } else if (fco instanceof WorkLocation) { - canvas.showColonyPanel(((WorkLocation)fco).getColony(), null); + widgets.showColonyPanel(((WorkLocation)fco).getColony(), null); } } @@ -1318,7 +1236,7 @@ public void displayObject(FreeColObject fco) { @Override public void displayStartChat(Player player, String message, boolean privateChat) { - canvas.displayStartChat(player.getName(), message, privateChat); + widgets.displayStartChat(player.getName(), message, privateChat); } /** @@ -1326,7 +1244,7 @@ public void displayStartChat(Player player, String message, */ @Override public boolean isClientOptionsDialogShowing() { - return canvas != null && canvas.isClientOptionsDialogShowing(); + return widgets.isClientOptionsDialogShowing(); } /** @@ -1370,6 +1288,15 @@ public void removeDialog(FreeColDialog fcd) { canvas.dialogRemove(fcd); } + /** + * {@inheritDoc} + */ + @Override + public void removeTradeRoutePanel(FreeColPanel panel) { + canvas.remove(panel); + widgets.cancelTradeRouteInput(); + } + /** * {@inheritDoc} */ @@ -1383,7 +1310,7 @@ public void restoreSavedSize(Component comp, Dimension size) { */ @Override public void showAboutPanel() { - canvas.showAboutPanel(); + widgets.showAboutPanel(); } /** @@ -1391,7 +1318,7 @@ public void showAboutPanel() { */ @Override public BuildQueuePanel showBuildQueuePanel(Colony colony) { - return canvas.showBuildQueuePanel(colony); + return widgets.showBuildQueuePanel(colony); } /** @@ -1400,7 +1327,7 @@ public BuildQueuePanel showBuildQueuePanel(Colony colony) { @Override public void showCaptureGoodsDialog(final Unit unit, List gl, DialogHandler> handler) { - canvas.showCaptureGoodsDialog(unit, gl, handler); + widgets.showCaptureGoodsDialog(unit, gl, handler); } /** @@ -1417,7 +1344,7 @@ public void showChatPanel() { @Override public void showChooseFoundingFatherDialog(final List ffs, DialogHandler handler) { - canvas.showChooseFoundingFatherDialog(ffs, handler); + widgets.showChooseFoundingFatherDialog(ffs, handler); } /** @@ -1427,7 +1354,7 @@ public void showChooseFoundingFatherDialog(final List ffs, public void showClientOptionsDialog() { OptionGroup group = null; try { - group = canvas.showClientOptionsDialog(); + group = widgets.showClientOptionsDialog(); } finally { resetMenuBar(); if (group != null) { @@ -1450,7 +1377,7 @@ public void showClientOptionsDialog() { */ @Override public ColonyPanel showColonyPanel(Colony colony, Unit unit) { - return canvas.showColonyPanel(colony, unit); + return widgets.showColonyPanel(colony, unit); } /** @@ -1458,7 +1385,7 @@ public ColonyPanel showColonyPanel(Colony colony, Unit unit) { */ @Override public void showColopediaPanel(String nodeId) { - canvas.showColopediaPanel(nodeId); + widgets.showColopediaPanel(nodeId); } /** @@ -1466,7 +1393,7 @@ public void showColopediaPanel(String nodeId) { */ @Override public ColorChooserPanel showColorChooserPanel(ActionListener al) { - return canvas.showColorChooserPanel(al); + return widgets.showColorChooserPanel(al); } /** @@ -1474,7 +1401,7 @@ public ColorChooserPanel showColorChooserPanel(ActionListener al) { */ @Override public void showCompactLabourReport() { - canvas.showCompactLabourReport(); + widgets.showCompactLabourReport(); } /** @@ -1482,7 +1409,7 @@ public void showCompactLabourReport() { */ @Override public void showCompactLabourReport(UnitData unitData) { - canvas.showCompactLabourReport(unitData); + widgets.showCompactLabourReport(unitData); } /** @@ -1490,7 +1417,7 @@ public void showCompactLabourReport(UnitData unitData) { */ @Override public void showDeclarationPanel() { - canvas.showDeclarationPanel(); + widgets.showDeclarationPanel(); } /** @@ -1500,7 +1427,7 @@ public void showDeclarationPanel() { public OptionGroup showDifficultyDialog(Specification spec, OptionGroup group, boolean editable) { - return canvas.showDifficultyDialog(spec, group, editable); + return widgets.showDifficultyDialog(spec, group, editable); } /** @@ -1509,7 +1436,7 @@ public OptionGroup showDifficultyDialog(Specification spec, @Override public void showDumpCargoDialog(Unit unit, DialogHandler> handler) { - canvas.showDumpCargoDialog(unit, handler); + widgets.showDumpCargoDialog(unit, handler); } /** @@ -1517,7 +1444,15 @@ public void showDumpCargoDialog(Unit unit, */ @Override public boolean showEditOptionDialog(Option option) { - return canvas.showEditOptionDialog(option); + return widgets.showEditOptionDialog(option); + } + + /** + * {@inheritDoc} + */ + @Override + public IndianSettlement showEditSettlementDialog(IndianSettlement settlement) { + return widgets.showEditSettlementDialog(settlement); } /** @@ -1527,7 +1462,7 @@ public boolean showEditOptionDialog(Option option) { public void showEmigrationDialog(final Player player, final boolean fountainOfYouth, DialogHandler handler) { - canvas.showEmigrationDialog(player, fountainOfYouth, handler); + widgets.showEmigrationDialog(player, fountainOfYouth, handler); } /** @@ -1536,7 +1471,7 @@ public void showEmigrationDialog(final Player player, @Override public void showEndTurnDialog(final List units, DialogHandler handler) { - canvas.showEndTurnDialog(units, handler); + widgets.showEndTurnDialog(units, handler); } /** @@ -1544,7 +1479,7 @@ public void showEndTurnDialog(final List units, */ @Override protected void showErrorMessage(String message, Runnable callback) { - canvas.showErrorMessage(message, callback); + widgets.showErrorMessage(message, callback); } /** @@ -1552,7 +1487,7 @@ protected void showErrorMessage(String message, Runnable callback) { */ @Override public void showEuropePanel() { - canvas.showEuropePanel(); + widgets.showEuropePanel(); } /** @@ -1560,7 +1495,7 @@ public void showEuropePanel() { */ @Override public void showEventPanel(String header, String image, String footer) { - canvas.showEventPanel(header, image, footer); + widgets.showEventPanel(header, image, footer); } /** @@ -1568,7 +1503,7 @@ public void showEventPanel(String header, String image, String footer) { */ @Override public void showFindSettlementPanel() { - canvas.showFindSettlementPanel(); + widgets.showFindSettlementPanel(); } /** @@ -1578,8 +1513,8 @@ public void showFindSettlementPanel() { public void showFirstContactDialog(final Player player, final Player other, final Tile tile, int settlementCount, DialogHandler handler) { - canvas.showFirstContactDialog(player, other, tile, settlementCount, - handler); + widgets.showFirstContactDialog(player, other, tile, settlementCount, + handler); } /** @@ -1587,7 +1522,7 @@ public void showFirstContactDialog(final Player player, final Player other, */ @Override public OptionGroup showGameOptionsDialog(boolean editable) { - return canvas.showGameOptionsDialog(editable); + return widgets.showGameOptionsDialog(editable); } /** @@ -1595,7 +1530,7 @@ public OptionGroup showGameOptionsDialog(boolean editable) { */ @Override public void showHighScoresPanel(String messageId, List scores) { - canvas.showHighScoresPanel(messageId, scores); + widgets.showHighScoresPanel(messageId, scores); } /** @@ -1603,7 +1538,7 @@ public void showHighScoresPanel(String messageId, List scores) { */ @Override public void showIndianSettlement(IndianSettlement indianSettlement) { - canvas.showIndianSettlementPanel(indianSettlement); + widgets.showIndianSettlementPanel(indianSettlement); } /** @@ -1625,7 +1560,7 @@ public InformationPanel showInformationPanel(FreeColObject displayObject, icon = new ImageIcon(imageLibrary.getScaledUnitImage((Unit)displayObject)); tile = ((Unit)displayObject).getTile(); } - return canvas.showInformationPanel(displayObject, tile, icon, template); + return widgets.showInformationPanel(displayObject, tile, icon, template); } /** @@ -1633,7 +1568,7 @@ public InformationPanel showInformationPanel(FreeColObject displayObject, */ @Override public File showLoadDialog(File directory, String extension) { - return canvas.showLoadDialog(directory, extension); + return widgets.showLoadDialog(directory, extension); } /** @@ -1642,7 +1577,7 @@ public File showLoadDialog(File directory, String extension) { @Override public LoadingSavegameInfo showLoadingSavegameDialog(boolean publicServer, boolean singlePlayer) { - return canvas.showLoadingSavegameDialog(publicServer, singlePlayer); + return widgets.showLoadingSavegameDialog(publicServer, singlePlayer); } /** @@ -1650,7 +1585,7 @@ public LoadingSavegameInfo showLoadingSavegameDialog(boolean publicServer, */ @Override public void showLogFilePanel() { - canvas.showLogFilePanel(); + widgets.showLogFilePanel(); } /** @@ -1676,7 +1611,7 @@ public void showMainTitle() { */ @Override public OptionGroup showMapGeneratorOptionsDialog(boolean editable) { - return canvas.showMapGeneratorOptionsDialog(editable); + return widgets.showMapGeneratorOptionsDialog(editable); } /** @@ -1684,7 +1619,7 @@ public OptionGroup showMapGeneratorOptionsDialog(boolean editable) { */ @Override public Dimension showMapSizeDialog() { - return canvas.showMapSizeDialog(); + return widgets.showMapSizeDialog(); } /** @@ -1692,7 +1627,7 @@ public Dimension showMapSizeDialog() { */ @Override public void showModelMessages(List modelMessages) { - canvas.showModelMessages(modelMessages); + widgets.showModelMessages(modelMessages); } /** @@ -1702,7 +1637,7 @@ public void showModelMessages(List modelMessages) { public void showMonarchDialog(final MonarchAction action, StringTemplate template, String monarchKey, DialogHandler handler) { - canvas.showMonarchDialog(action, template, monarchKey, handler); + widgets.showMonarchDialog(action, template, monarchKey, handler); } /** @@ -1713,7 +1648,7 @@ public void showNamingDialog(StringTemplate template, final String defaultName, final Unit unit, DialogHandler handler) { - canvas.showNamingDialog(template, defaultName, unit, handler); + widgets.showNamingDialog(template, defaultName, unit, handler); } /** @@ -1723,7 +1658,7 @@ public void showNamingDialog(StringTemplate template, public void showNativeDemandDialog(Unit unit, Colony colony, GoodsType type, int amount, DialogHandler handler) { - canvas.showNativeDemandDialog(unit, colony, type, amount, handler); + widgets.showNativeDemandDialog(unit, colony, type, amount, handler); } /** @@ -1734,7 +1669,7 @@ public DiplomaticTrade showNegotiationDialog(FreeColGameObject our, FreeColGameObject other, DiplomaticTrade agreement, StringTemplate comment) { - return canvas.showNegotiationDialog(our, other, agreement, comment); + return widgets.showNegotiationDialog(our, other, agreement, comment); } /** @@ -1742,7 +1677,7 @@ public DiplomaticTrade showNegotiationDialog(FreeColGameObject our, */ @Override public void showNewPanel(Specification spec) { - canvas.showNewPanel(spec); + widgets.showNewPanel(spec); } /** @@ -1750,7 +1685,7 @@ public void showNewPanel(Specification spec) { */ @Override public Parameters showParametersDialog() { - return canvas.showParametersDialog(); + return widgets.showParametersDialog(); } /** @@ -1759,7 +1694,7 @@ public Parameters showParametersDialog() { @Override public boolean showPreCombatDialog(Unit attacker, FreeColGameObject defender, Tile tile) { - return canvas.showPreCombatDialog(attacker, defender, tile); + return widgets.showPreCombatDialog(attacker, defender, tile); } /** @@ -1767,7 +1702,7 @@ public boolean showPreCombatDialog(Unit attacker, */ @Override public void showPurchasePanel() { - canvas.showPurchasePanel(); + widgets.showPurchasePanel(); } /** @@ -1775,7 +1710,7 @@ public void showPurchasePanel() { */ @Override public void showRecruitPanel() { - canvas.showRecruitPanel(); + widgets.showRecruitPanel(); } /** @@ -1783,7 +1718,7 @@ public void showRecruitPanel() { */ @Override public void showReportCargoPanel() { - canvas.showReportCargoPanel(); + widgets.showReportCargoPanel(); } /** @@ -1791,7 +1726,7 @@ public void showReportCargoPanel() { */ @Override public void showReportColonyPanel() { - canvas.showReportColonyPanel(); + widgets.showReportColonyPanel(); } /** @@ -1799,7 +1734,7 @@ public void showReportColonyPanel() { */ @Override public void showReportContinentalCongressPanel() { - canvas.showReportContinentalCongressPanel(); + widgets.showReportContinentalCongressPanel(); } /** @@ -1807,7 +1742,7 @@ public void showReportContinentalCongressPanel() { */ @Override public void showReportEducationPanel() { - canvas.showReportEducationPanel(); + widgets.showReportEducationPanel(); } /** @@ -1815,7 +1750,7 @@ public void showReportEducationPanel() { */ @Override public void showReportExplorationPanel() { - canvas.showReportExplorationPanel(); + widgets.showReportExplorationPanel(); } /** @@ -1823,7 +1758,7 @@ public void showReportExplorationPanel() { */ @Override public void showReportForeignAffairPanel() { - canvas.showReportForeignAffairPanel(); + widgets.showReportForeignAffairPanel(); } /** @@ -1831,7 +1766,7 @@ public void showReportForeignAffairPanel() { */ @Override public void showReportHistoryPanel() { - canvas.showReportHistoryPanel(); + widgets.showReportHistoryPanel(); } /** @@ -1839,7 +1774,7 @@ public void showReportHistoryPanel() { */ @Override public void showReportIndianPanel() { - canvas.showReportIndianPanel(); + widgets.showReportIndianPanel(); } /** @@ -1847,7 +1782,7 @@ public void showReportIndianPanel() { */ @Override public void showReportLabourPanel() { - canvas.showReportLabourPanel(); + widgets.showReportLabourPanel(); } /** @@ -1857,8 +1792,8 @@ public void showReportLabourPanel() { public void showReportLabourDetailPanel(UnitType unitType, java.util.Map> data, TypeCountMap unitCount, List colonies) { - canvas.showReportLabourDetailPanel(unitType, data, unitCount, - colonies); + widgets.showReportLabourDetailPanel(unitType, data, unitCount, + colonies); } /** @@ -1866,7 +1801,7 @@ public void showReportLabourDetailPanel(UnitType unitType, */ @Override public void showReportMilitaryPanel() { - canvas.showReportMilitaryPanel(); + widgets.showReportMilitaryPanel(); } /** @@ -1874,7 +1809,7 @@ public void showReportMilitaryPanel() { */ @Override public void showReportNavalPanel() { - canvas.showReportNavalPanel(); + widgets.showReportNavalPanel(); } /** @@ -1882,7 +1817,7 @@ public void showReportNavalPanel() { */ @Override public void showReportProductionPanel() { - canvas.showReportProductionPanel(); + widgets.showReportProductionPanel(); } /** @@ -1890,7 +1825,7 @@ public void showReportProductionPanel() { */ @Override public void showReportReligiousPanel() { - canvas.showReportReligiousPanel(); + widgets.showReportReligiousPanel(); } /** @@ -1898,7 +1833,7 @@ public void showReportReligiousPanel() { */ @Override public void showReportRequirementsPanel() { - canvas.showReportRequirementsPanel(); + widgets.showReportRequirementsPanel(); } /** @@ -1906,7 +1841,7 @@ public void showReportRequirementsPanel() { */ @Override public void showReportTradePanel() { - canvas.showReportTradePanel(); + widgets.showReportTradePanel(); } /** @@ -1914,7 +1849,7 @@ public void showReportTradePanel() { */ @Override public void showReportTurnPanel(List messages) { - canvas.showReportTurnPanel(messages); + widgets.showReportTurnPanel(messages); } /** @@ -1922,7 +1857,7 @@ public void showReportTurnPanel(List messages) { */ @Override public String showRiverStyleDialog(List styles) { - return canvas.showRiverStyleDialog(styles); + return widgets.showRiverStyleDialog(styles); } /** @@ -1930,7 +1865,7 @@ public String showRiverStyleDialog(List styles) { */ @Override public File showSaveDialog(File directory, String defaultName) { - return canvas.showSaveDialog(directory, defaultName); + return widgets.showSaveDialog(directory, defaultName); } /** @@ -1938,7 +1873,7 @@ public File showSaveDialog(File directory, String defaultName) { */ @Override public Dimension showScaleMapSizeDialog() { - return canvas.showScaleMapSizeDialog(); + return widgets.showScaleMapSizeDialog(); } /** @@ -1947,7 +1882,7 @@ public Dimension showScaleMapSizeDialog() { @Override public int showSelectAmountDialog(GoodsType goodsType, int available, int defaultAmount, boolean needToPay) { - return canvas.showSelectAmountDialog(goodsType, available, + return widgets.showSelectAmountDialog(goodsType, available, defaultAmount, needToPay); } @@ -1956,7 +1891,7 @@ public int showSelectAmountDialog(GoodsType goodsType, int available, */ @Override public Location showSelectDestinationDialog(Unit unit) { - return canvas.showSelectDestinationDialog(unit); + return widgets.showSelectDestinationDialog(unit); } /** @@ -1965,7 +1900,7 @@ public Location showSelectDestinationDialog(Unit unit) { @Override public int showSelectTributeAmountDialog(StringTemplate question, int maximum) { - return canvas.showSelectTributeAmountDialog(question, maximum); + return widgets.showSelectTributeAmountDialog(question, maximum); } /** @@ -1982,7 +1917,13 @@ public void showServerListPanel(List serverList) { @Override public void showStartGamePanel(Game game, Player player, boolean singlePlayerMode) { - canvas.showStartGamePanel(game, player, singlePlayerMode); + if (game == null) { + logger.warning("StartGamePanel requires game != null."); + } else if (player == null) { + logger.warning("StartGamePanel requires player != null."); + } else { + canvas.showStartGamePanel(singlePlayerMode); + } } /** @@ -1991,7 +1932,7 @@ public void showStartGamePanel(Game game, Player player, @Override public void showStatisticsPanel(java.util.Map serverStats, java.util.Map clientStats) { - canvas.showStatisticsPanel(serverStats, clientStats); + widgets.showStatisticsPanel(serverStats, clientStats); } /** @@ -2007,7 +1948,7 @@ public void showStatusPanel(String message) { */ @Override public void showTilePanel(Tile tile) { - canvas.showTilePanel(tile); + widgets.showTilePanel(tile); } /** @@ -2017,7 +1958,9 @@ public void showTilePanel(Tile tile) { public void showTilePopup(int x, int y) { final Tile tile = canvas.convertToMapTile(x, y); if (tile == null) return; - canvas.showTilePopup(tile); + if (!canvas.showTilePopup(tile) && tile.isExplored()) { + widgets.showTilePanel(tile); + } } /** @@ -2025,7 +1968,7 @@ public void showTilePopup(int x, int y) { */ @Override public TradeRouteInputPanel showTradeRouteInputPanel(TradeRoute newRoute) { - return canvas.showTradeRouteInputPanel(newRoute); + return widgets.showTradeRouteInputPanel(newRoute); } /** @@ -2033,7 +1976,7 @@ public TradeRouteInputPanel showTradeRouteInputPanel(TradeRoute newRoute) { */ @Override public void showTradeRoutePanel(Unit unit) { - canvas.showTradeRoutePanel(unit); + widgets.showTradeRoutePanel(unit); } /** @@ -2041,7 +1984,7 @@ public void showTradeRoutePanel(Unit unit) { */ @Override public void showTrainPanel() { - canvas.showTrainPanel(); + widgets.showTrainPanel(); } /** @@ -2049,7 +1992,7 @@ public void showTrainPanel() { */ @Override public void showVictoryDialog(DialogHandler handler) { - canvas.showVictoryDialog(handler); + widgets.showVictoryDialog(handler); } /** @@ -2057,7 +2000,7 @@ public void showVictoryDialog(DialogHandler handler) { */ @Override public boolean showWarehouseDialog(Colony colony) { - return canvas.showWarehouseDialog(colony); + return widgets.showWarehouseDialog(colony); } /** @@ -2065,7 +2008,7 @@ public boolean showWarehouseDialog(Colony colony) { */ @Override public void showWorkProductionPanel(Unit unit) { - canvas.showWorkProductionPanel(unit); + widgets.showWorkProductionPanel(unit); } /** @@ -2073,6 +2016,6 @@ public void showWorkProductionPanel(Unit unit) { */ @Override public void updateEuropeanSubpanels() { - canvas.updateEuropeanSubpanels(); + widgets.updateEuropeanSubpanels(); } } diff --git a/src/net/sf/freecol/client/gui/Widgets.java b/src/net/sf/freecol/client/gui/Widgets.java new file mode 100644 index 0000000000..88039255b0 --- /dev/null +++ b/src/net/sf/freecol/client/gui/Widgets.java @@ -0,0 +1,1412 @@ +/** + * Copyright (C) 2002-2019 The FreeCol Team + * + * This file is part of FreeCol. + * + * FreeCol is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * FreeCol is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FreeCol. If not, see . + */ + +package net.sf.freecol.client.gui; + +import java.awt.event.ActionListener; +import java.awt.Dimension; +import java.awt.Image; +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.filechooser.FileFilter; +import javax.swing.ImageIcon; +import javax.swing.SwingUtilities; + +import net.sf.freecol.FreeCol; +import net.sf.freecol.client.ClientOptions; +import net.sf.freecol.client.FreeColClient; +import net.sf.freecol.client.gui.panel.AboutPanel; +import net.sf.freecol.client.gui.panel.BuildQueuePanel; +import net.sf.freecol.client.gui.dialog.CaptureGoodsDialog; +import net.sf.freecol.client.gui.panel.ChatPanel; +import net.sf.freecol.client.gui.dialog.ChooseFoundingFatherDialog; +import net.sf.freecol.client.gui.dialog.ClientOptionsDialog; +import net.sf.freecol.client.gui.panel.ColonyPanel; +import net.sf.freecol.client.gui.panel.colopedia.ColopediaPanel; +import net.sf.freecol.client.gui.panel.ColorChooserPanel; +import net.sf.freecol.client.gui.panel.report.CompactLabourReport; +import net.sf.freecol.client.gui.dialog.ConfirmDeclarationDialog; +import net.sf.freecol.client.gui.panel.DeclarationPanel; +import net.sf.freecol.client.gui.dialog.DifficultyDialog; +import net.sf.freecol.client.gui.dialog.DumpCargoDialog; +import net.sf.freecol.client.gui.dialog.EditOptionDialog; +import net.sf.freecol.client.gui.dialog.EditSettlementDialog; +import net.sf.freecol.client.gui.dialog.EmigrationDialog; +import net.sf.freecol.client.gui.dialog.EndTurnDialog; +import net.sf.freecol.client.gui.panel.ErrorPanel; +import net.sf.freecol.client.gui.panel.EuropePanel; +import net.sf.freecol.client.gui.panel.EventPanel; +import net.sf.freecol.client.gui.panel.FindSettlementPanel; +import net.sf.freecol.client.gui.dialog.FirstContactDialog; +import net.sf.freecol.client.gui.dialog.FreeColChoiceDialog; +import net.sf.freecol.client.gui.dialog.FreeColConfirmDialog; +import net.sf.freecol.client.gui.dialog.FreeColDialog; +import net.sf.freecol.client.gui.panel.FreeColPanel; +import net.sf.freecol.client.gui.dialog.FreeColStringInputDialog; +import net.sf.freecol.client.gui.dialog.GameOptionsDialog; +import net.sf.freecol.client.gui.panel.IndianSettlementPanel; +import net.sf.freecol.client.gui.panel.InformationPanel; +import net.sf.freecol.client.gui.panel.report.LabourData.UnitData; +import net.sf.freecol.client.gui.dialog.LoadDialog; +import net.sf.freecol.client.gui.dialog.LoadingSavegameDialog; +import net.sf.freecol.client.gui.panel.MainPanel; +import net.sf.freecol.client.gui.panel.MapEditorTransformPanel; +import net.sf.freecol.client.gui.dialog.MapGeneratorOptionsDialog; +import net.sf.freecol.client.gui.dialog.MapSizeDialog; +import net.sf.freecol.client.gui.dialog.MonarchDialog; +import net.sf.freecol.client.gui.dialog.NativeDemandDialog; +import net.sf.freecol.client.gui.dialog.NegotiationDialog; +import net.sf.freecol.client.gui.panel.NewPanel; +import net.sf.freecol.client.gui.dialog.Parameters; +import net.sf.freecol.client.gui.dialog.ParametersDialog; +import net.sf.freecol.client.gui.dialog.PreCombatDialog; +import net.sf.freecol.client.gui.panel.PurchasePanel; +import net.sf.freecol.client.gui.panel.RecruitPanel; +import net.sf.freecol.client.gui.panel.report.ReportCargoPanel; +import net.sf.freecol.client.gui.panel.report.ReportClassicColonyPanel; +import net.sf.freecol.client.gui.panel.report.ReportCompactColonyPanel; +import net.sf.freecol.client.gui.panel.report.ReportContinentalCongressPanel; +import net.sf.freecol.client.gui.panel.report.ReportEducationPanel; +import net.sf.freecol.client.gui.panel.report.ReportExplorationPanel; +import net.sf.freecol.client.gui.panel.report.ReportForeignAffairPanel; +import net.sf.freecol.client.gui.panel.report.ReportHighScoresPanel; +import net.sf.freecol.client.gui.panel.report.ReportHistoryPanel; +import net.sf.freecol.client.gui.panel.report.ReportIndianPanel; +import net.sf.freecol.client.gui.panel.report.ReportLabourDetailPanel; +import net.sf.freecol.client.gui.panel.report.ReportLabourPanel; +import net.sf.freecol.client.gui.panel.report.ReportMilitaryPanel; +import net.sf.freecol.client.gui.panel.report.ReportNavalPanel; +import net.sf.freecol.client.gui.panel.report.ReportPanel; +import net.sf.freecol.client.gui.panel.report.ReportProductionPanel; +import net.sf.freecol.client.gui.panel.report.ReportReligiousPanel; +import net.sf.freecol.client.gui.panel.report.ReportRequirementsPanel; +import net.sf.freecol.client.gui.panel.report.ReportTradePanel; +import net.sf.freecol.client.gui.panel.report.ReportTurnPanel; +import net.sf.freecol.client.gui.dialog.RiverStyleDialog; +import net.sf.freecol.client.gui.dialog.SaveDialog; +import net.sf.freecol.client.gui.dialog.ScaleMapSizeDialog; +import net.sf.freecol.client.gui.dialog.SelectAmountDialog; +import net.sf.freecol.client.gui.dialog.SelectDestinationDialog; +import net.sf.freecol.client.gui.dialog.SelectTributeAmountDialog; +import net.sf.freecol.client.gui.panel.ServerListPanel; +import net.sf.freecol.client.gui.panel.StartGamePanel; +import net.sf.freecol.client.gui.panel.StatisticsPanel; +import net.sf.freecol.client.gui.panel.StatusPanel; +import net.sf.freecol.client.gui.panel.TilePanel; +import net.sf.freecol.client.gui.panel.TradeRouteInputPanel; +import net.sf.freecol.client.gui.panel.TradeRoutePanel; +import net.sf.freecol.client.gui.panel.TrainPanel; +import net.sf.freecol.client.gui.dialog.VictoryDialog; +import net.sf.freecol.client.gui.dialog.WarehouseDialog; +import net.sf.freecol.client.gui.panel.WorkProductionPanel; + +import net.sf.freecol.common.i18n.Messages; +import net.sf.freecol.common.io.FreeColDataFile; +import net.sf.freecol.common.model.Colony; +import net.sf.freecol.common.model.DiplomaticTrade; +import net.sf.freecol.common.model.FoundingFather; +import net.sf.freecol.common.model.FreeColObject; +import net.sf.freecol.common.model.FreeColGameObject; +import net.sf.freecol.common.model.Game; +import net.sf.freecol.common.model.Goods; +import net.sf.freecol.common.model.GoodsType; +import net.sf.freecol.common.model.HighScore; +import net.sf.freecol.common.model.IndianSettlement; +import net.sf.freecol.common.model.Location; +import net.sf.freecol.common.model.ModelMessage; +import net.sf.freecol.common.model.Monarch.MonarchAction; +import net.sf.freecol.common.model.Player; +import net.sf.freecol.common.model.Specification; +import net.sf.freecol.common.model.StringTemplate; +import net.sf.freecol.common.model.Tile; +import net.sf.freecol.common.model.TradeRoute; +import net.sf.freecol.common.model.TypeCountMap; +import net.sf.freecol.common.model.Unit; +import net.sf.freecol.common.model.UnitType; +import net.sf.freecol.common.option.Option; +import net.sf.freecol.common.option.OptionGroup; +import static net.sf.freecol.common.util.CollectionUtils.*; +import net.sf.freecol.common.util.Introspector; +import static net.sf.freecol.common.util.StringUtils.*; +import net.sf.freecol.common.util.Utils; + + +/** + * Container for all the higher level dialogs and panels. + * Moved here so that Canvas is more manageable. + */ +public final class Widgets { + + private static final Logger logger = Logger.getLogger(Widgets.class.getName()); + + private static final List> EUROPE_CLASSES + = makeUnmodifiableList(RecruitPanel.class, + PurchasePanel.class, + TrainPanel.class); + + /** The game client. */ + private final FreeColClient freeColClient; + + /** The image library to create icons etc with. */ + private final ImageLibrary imageLibrary; + + /** The canvas to write to. */ + private final Canvas canvas; + + + /** A wrapper class for non-modal dialogs. */ + private class DialogCallback implements Runnable { + + /** The dialog to show. */ + private final FreeColDialog fcd; + + /** An optional tile to guide the dialog placement. */ + private final Tile tile; + + /** The handler for the dialog response. */ + private final DialogHandler handler; + + + /** + * Constructor. + * + * @param fcd The parent {@code FreeColDialog}. + * @param tile An optional {@code Tile} to display. + * @param handler The {@code DialogHandler} to call when run. + */ + public DialogCallback(FreeColDialog fcd, Tile tile, + DialogHandler handler) { + this.fcd = fcd; + this.tile = tile; + this.handler = handler; + } + + + // Implement Runnable + + @Override + public void run() { + // Display the dialog... + canvas.viewFreeColDialog(fcd, tile); + // ...and use another thread to wait for a dialog response... + new Thread(fcd.toString()) { + @Override + public void run() { + while (!fcd.responded()) { + Utils.delay(500, "Dialog interrupted."); + } + // ...before handling the result. + handler.handle(fcd.getResponse()); + } + }.start(); + } + }; + + + /** + * Create this wrapper class. + * + * @param canvas The {@code Canvas} to call out to. + */ + public Widgets(FreeColClient freeColClient, ImageLibrary imageLibrary, + Canvas canvas) { + this.freeColClient = freeColClient; + this.imageLibrary = imageLibrary; + this.canvas = canvas; + } + + + // Simple utilities + + private FreeColFrame getFrame() { + return this.canvas.getParentFrame(); + } + + /** + * Make image icon from an image. + * Use only if you know having null is possible! + * + * @param image The {@code Image} to create an icon for. + * @return The {@code ImageIcon}. + */ + private static ImageIcon createImageIcon(Image image) { + return (image==null) ? null : new ImageIcon(image); + } + + /** + * Make image icon from an object. + * + * @param display The FreeColObject to find an icon for. + * @return The {@code ImageIcon} found. + */ + private ImageIcon createObjectImageIcon(FreeColObject display) { + return (display == null) ? null + : createImageIcon(this.imageLibrary.getObjectImage(display, 2f)); + } + + // Generic dialogs + + /** + * Displays a modal dialog with text and a choice of options. + * + * @param The type to be returned from the dialog. + * @param tile An optional {@code Tile} to make visible (not + * under the dialog!) + * @param obj An object that explains the choice for the user. + * @param icon An optional icon to display. + * @param cancelKey Key for the text of the optional cancel button. + * @param choices The {@code List} containing the ChoiceItems to + * create buttons for. + * @return The corresponding member of the values array to the selected + * option, or null if no choices available. + */ + public T showChoiceDialog(Tile tile, StringTemplate tmpl, + ImageIcon icon, String cancelKey, + List> choices) { + if (choices.isEmpty()) return null; + FreeColChoiceDialog dialog + = new FreeColChoiceDialog<>(freeColClient, getFrame(), true, + tmpl, icon, cancelKey, choices); + return canvas.showFreeColDialog(dialog, tile); + } + + /** + * Displays a modal dialog with a text and a ok/cancel option. + * + * @param tile An optional {@code Tile} to make visible (not + * under the dialog!) + * @param tmpl A {@code StringTemplate} to explain the choice. + * @param icon An optional icon to display. + * @param okKey The text displayed on the "ok"-button. + * @param cancelKey The text displayed on the "cancel"-button. + * @return True if the user clicked the "ok"-button. + */ + public boolean showConfirmDialog(Tile tile, StringTemplate tmpl, + ImageIcon icon, + String okKey, String cancelKey) { + FreeColConfirmDialog dialog + = new FreeColConfirmDialog(freeColClient, getFrame(), true, + tmpl, icon, okKey, cancelKey); + return canvas.showFreeColDialog(dialog, tile); + } + + /** + * Displays a modal dialog with a text field and a ok/cancel option. + * + * @param tile An optional tile to make visible (not under the dialog). + * @param tmpl A {@code StringTemplate} that explains the + * action to the user. + * @param defaultValue The default value appearing in the text field. + * @param okKey A key displayed on the "ok"-button. + * @param cancelKey A key displayed on the optional "cancel"-button. + * @return The text the user entered, or null if cancelled. + */ + public String showInputDialog(Tile tile, StringTemplate tmpl, + String defaultValue, + String okKey, String cancelKey) { + FreeColStringInputDialog dialog + = new FreeColStringInputDialog(freeColClient, getFrame(), true, + tmpl, defaultValue, + okKey, cancelKey); + return canvas.showFreeColDialog(dialog, tile); + } + + + // Simple front ends to display specific dialogs and panels + + /** + * Cancel the current trade route in a TradeRouteInputPanel. + */ + public void cancelTradeRouteInput() { + TradeRouteInputPanel panel + = canvas.getExistingFreeColPanel(TradeRouteInputPanel.class); + if (panel != null) { + panel.cancelTradeRoute(); + } + } + + /** + * Tells that a chat message was received. + * + * @param senderName The sender. + * @param message The chat message. + * @param privateChat True if this is a private message. + */ + public void displayStartChat(String senderName, String message, + boolean privateChat) { + StartGamePanel panel + = canvas.getExistingFreeColPanel(StartGamePanel.class); + if (panel != null) { + panel.displayChat(senderName, message, privateChat); + } + } + + /** + * Is the client options dialog present? + * + * @return True if the client options dialog is found. + */ + public boolean isClientOptionsDialogShowing() { + return canvas.getExistingFreeColDialog(ClientOptionsDialog.class) != null; + } + + /** + * Display the AboutPanel. + */ + public void showAboutPanel() { + AboutPanel panel + = new AboutPanel(freeColClient); + canvas.showSubPanel(panel, false); + } + + /** + * Show the BuildQueuePanel for a given colony. + * + * @param colony The {@code Colony} to show the build queue of. + * @return The {@code BuildQueuePanel}. + */ + public BuildQueuePanel showBuildQueuePanel(Colony colony) { + BuildQueuePanel panel + = canvas.getExistingFreeColPanel(BuildQueuePanel.class); + if (panel == null || panel.getColony() != colony) { + panel = new BuildQueuePanel(freeColClient, colony); + canvas.showSubPanel(panel, true); + } + return panel; + } + + /** + * Display the {@code CaptureGoodsDialog}. + * + * @param unit The {@code Unit} capturing goods. + * @param gl The list of {@code Goods} to choose from. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showCaptureGoodsDialog(Unit unit, List gl, + DialogHandler> handler) { + CaptureGoodsDialog dialog + = new CaptureGoodsDialog(freeColClient, getFrame(), + unit, gl); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, null, handler)); + } + + /** + * Displays the {@code ChooseFoundingFatherDialog}. + * + * @param ffs The {@code FoundingFather}s to choose from. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showChooseFoundingFatherDialog(List ffs, + DialogHandler handler) { + ChooseFoundingFatherDialog dialog + = new ChooseFoundingFatherDialog(freeColClient, getFrame(), + ffs); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, null, handler)); + } + + /** + * Displays a dialog for setting client options. + * + * @return The modified {@code OptionGroup}, or null if not modified. + */ + public OptionGroup showClientOptionsDialog() { + ClientOptionsDialog dialog + = new ClientOptionsDialog(freeColClient, getFrame()); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Displays the colony panel of the given {@code Colony}. + * Defends against duplicates as this can duplicate messages + * generated by multiple property change listeners registered + * against the same colony. + * + * @param colony The colony whose panel needs to be displayed. + * @param unit An optional {@code Unit} to select within the panel. + * @return The {@code ColonyPanel}. + */ + public ColonyPanel showColonyPanel(Colony colony, Unit unit) { + if (colony == null) return null; + ColonyPanel panel = canvas.getColonyPanel(colony); + if (panel == null) { + try { + panel = new ColonyPanel(freeColClient, colony); + } catch (Exception e) { + logger.log(Level.WARNING, "Exception in ColonyPanel for " + + colony.getId(), e); + return null; + } + canvas.showFreeColPanel(panel, colony.getTile(), true); + } else { + panel.requestFocus(); + } + if (unit != null) panel.setSelectedUnit(unit); + return panel; + } + + /** + * Show the colopedia entry for a given node. + * + * @param nodeId The node identifier to display. + */ + public void showColopediaPanel(String nodeId) { + ColopediaPanel panel + = new ColopediaPanel(freeColClient, nodeId); + canvas.showSubPanel(panel, true); + } + + /** + * Show a {@code ColorChooserPanel}. + * + * @param al An {@code ActionListener} to handle panel button + * presses. + * @return The {@code ColorChooserPanel} created. + */ + public ColorChooserPanel showColorChooserPanel(ActionListener al) { + ColorChooserPanel panel + = new ColorChooserPanel(freeColClient, al); + canvas.showFreeColPanel(panel, null, false); + return panel; + } + + /** + * Show the compact labour report. + */ + public void showCompactLabourReport() { + CompactLabourReport panel + = new CompactLabourReport(freeColClient); + panel.initialize(); + canvas.showSubPanel(panel, false); + + } + + /** + * Show the compact labour report for the specified unit data. + * + * @param unitData The {@code UnitData} to display. + */ + public void showCompactLabourReport(UnitData unitData) { + CompactLabourReport panel + = new CompactLabourReport(freeColClient, unitData); + panel.initialize(); + canvas.showSubPanel(panel, false); + } + + /** + * Display a dialog to confirm a declaration of independence. + * + * @return A list of names for a new nation. + */ + public List showConfirmDeclarationDialog() { + ConfirmDeclarationDialog dialog + = new ConfirmDeclarationDialog(freeColClient, getFrame()); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Display a panel showing the declaration of independence with + * animated signature. + */ + public void showDeclarationPanel() { + DeclarationPanel panel + = new DeclarationPanel(freeColClient); + canvas.showSubPanel(panel, Canvas.PopupPosition.CENTERED, false); + } + + /** + * Display the difficulty dialog for a given group. + * + * @param spec The enclosing {@code Specification}. + * @param group The {@code OptionGroup} containing the difficulty. + * @param editable If the options should be editable. + * @return The resulting {@code OptionGroup}. + */ + public OptionGroup showDifficultyDialog(Specification spec, + OptionGroup group, boolean editable) { + DifficultyDialog dialog + = new DifficultyDialog(freeColClient, getFrame(), + spec, group, editable); + OptionGroup ret = canvas.showFreeColDialog(dialog, null); + if (ret != null) FreeCol.setDifficulty(ret); + return ret; + } + + /** + * Displays the {@code DumpCargoDialog}. + * + * @param unit The {@code Unit} that is dumping. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showDumpCargoDialog(Unit unit, DialogHandler> handler) { + DumpCargoDialog dialog + = new DumpCargoDialog(freeColClient, getFrame(), unit); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, unit.getTile(), handler)); + } + + /** + * Display the EditOptionDialog. + * + * @param op The {@code Option} to edit. + * @return The response returned by the dialog. + */ + public boolean showEditOptionDialog(Option op) { + if (op == null) return false; + EditOptionDialog dialog + = new EditOptionDialog(freeColClient, getFrame(), op); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Display the EditSettlementDialog. + * + * @param is The {@code IndianSettlement} to edit. + * @return The response returned by the dialog. + */ + public IndianSettlement showEditSettlementDialog(IndianSettlement is) { + EditSettlementDialog dialog + = new EditSettlementDialog(freeColClient, getFrame(), is); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Shows the panel that allows the user to choose which unit will emigrate + * from Europe. + * + * @param player The {@code Player} whose unit is emigrating. + * @param fountainOfYouth Is this dialog displayed as a result of a + * fountain of youth. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showEmigrationDialog(Player player, boolean fountainOfYouth, + DialogHandler handler) { + EmigrationDialog dialog + = new EmigrationDialog(freeColClient, getFrame(), + player.getEurope(), fountainOfYouth); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, null, handler)); + } + + /** + * Display the EndTurnDialog with given units that could still move. + * + * @param units A list of {@code Unit}s that could still move. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showEndTurnDialog(List units, + DialogHandler handler) { + EndTurnDialog dialog + = new EndTurnDialog(freeColClient, getFrame(), + units); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, null, handler)); + } + + /** + * Displays an error message. + * + * @param message The message to display. + * @param callback Optional routine to run when the error panel is closed. + */ + public void showErrorMessage(String message, Runnable callback) { + if (message != null) { + ErrorPanel errorPanel = new ErrorPanel(freeColClient, message); + if (callback != null) errorPanel.addClosingCallback(callback); + canvas.showSubPanel(errorPanel, true); + } + } + + /** + * Displays the {@code EuropePanel}. + * + * @see EuropePanel + */ + public void showEuropePanel() { + if (freeColClient.getGame() == null) return; + EuropePanel panel + = canvas.getExistingFreeColPanel(EuropePanel.class); + if (panel == null) { + panel = new EuropePanel(freeColClient, (canvas.getHeight() > 780)); + panel.addClosingCallback(() -> { + for (Class c: EUROPE_CLASSES) { + FreeColPanel p = canvas.getExistingFreeColPanel(c); + if (p != null) canvas.remove(p); + } + }); + canvas.showSubPanel(panel, true); + } + } + + /** + * Display an event panel. + * + * @param header The title. + * @param image A resource key for the image to display. + * @param footer Optional footer text. + */ + public void showEventPanel(String header, String image, String footer) { + EventPanel panel + = new EventPanel(freeColClient, header, image, footer); + canvas.showSubPanel(panel, Canvas.PopupPosition.CENTERED, false); + } + + /** + * Display the FindSettlementPanel. + */ + public void showFindSettlementPanel() { + FindSettlementPanel panel + = new FindSettlementPanel(freeColClient); + canvas.showSubPanel(panel, Canvas.PopupPosition.ORIGIN, true); + } + + /** + * Display the first contact dialog (which is really just a + * non-modal confirm dialog). + * + * @param player The {@code Player} making contact. + * @param other The {@code Player} to contact. + * @param tile An optional {@code Tile} on offer. + * @param settlementCount The number of settlements the other + * player has (from the server, other.getNumberOfSettlements() + * is wrong here!). + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showFirstContactDialog(Player player, Player other, + Tile tile, int settlementCount, + DialogHandler handler) { + FirstContactDialog dialog + = new FirstContactDialog(freeColClient, getFrame(), + player, other, tile, settlementCount); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, tile, handler)); + } + + /** + * Display the GameOptionsDialog. + * + * @param editable Should the game options be editable? + * @return The {@code OptionGroup} selected. + */ + public OptionGroup showGameOptionsDialog(boolean editable) { + GameOptionsDialog dialog + = new GameOptionsDialog(freeColClient, getFrame(), editable); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Displays the high scores panel. + * + * @param messageId An optional message to add to the high scores panel. + * @param scores The list of {@code HighScore}s to display. + */ + public void showHighScoresPanel(String messageId, List scores) { + ReportHighScoresPanel panel + = new ReportHighScoresPanel(freeColClient, messageId, scores); + canvas.showSubPanel(panel, Canvas.PopupPosition.CENTERED, true); + } + + /** + * Displays the panel of the given native settlement. + * + * @param is The {@code IndianSettlement} to display. + */ + public void showIndianSettlementPanel(IndianSettlement is) { + IndianSettlementPanel panel + = new IndianSettlementPanel(freeColClient, is); + canvas.showFreeColPanel(panel, is.getTile(), true); + } + + /** + * Shows a message with some information and an "OK"-button. + * + * @param displayObject Optional object for displaying an icon. + * @param tmpl The {@code StringTemplate} to display. + * @return The {@code InformationPanel} that is displayed. + */ + public InformationPanel showInformationPanel(FreeColObject displayObject, + StringTemplate tmpl) { + ImageIcon icon = null; + Tile tile = null; + if (displayObject != null) { + icon = createObjectImageIcon(displayObject); + tile = (displayObject instanceof Location) + ? ((Location)displayObject).getTile() + : null; + } + return showInformationPanel(displayObject, tile, icon, tmpl); + } + + /** + * Shows a message with some information and an "OK"-button. + * + * @param displayObject Optional object for displaying. + * @param tile The Tile the object is at. + * @param icon The icon to display for the object. + * @param tmpl The {@code StringTemplate} to display. + * @return The {@code InformationPanel} that is displayed. + */ + public InformationPanel showInformationPanel(FreeColObject displayObject, + Tile tile, ImageIcon icon, + StringTemplate tmpl) { + String text = Messages.message(tmpl); + InformationPanel panel = new InformationPanel(freeColClient, text, + displayObject, icon); + canvas.showFreeColPanel(panel, tile, true); + return panel; + } + + /** + * Displays a dialog where the user may choose a file. + * + * @param directory The directory containing the files. + * @param extension An extension to select with. + * @return The selected {@code File}. + */ + public File showLoadDialog(File directory, String extension) { + FileFilter[] filters = new FileFilter[] { + FreeColDataFile.getFileFilter(extension) + }; + File file = null; + LoadDialog dialog; + for (;;) { + dialog = new LoadDialog(freeColClient, getFrame(), + directory, filters); + file = canvas.showFreeColDialog(dialog, null); + if (file == null || file.isFile()) break; + showErrorMessage(Messages.message(FreeCol.badFile("error.noSuchFile", file)), null); + } + return file; + } + + /** + * Displays a dialog for setting options when loading a savegame. The + * settings can be retrieved directly from {@link LoadingSavegameDialog} + * after calling this method. + * + * @param pubSer Default value. + * @param single Default value. + * @return The {@code LoadingSavegameInfo} if the dialog was accepted, + * or null otherwise. + */ + public LoadingSavegameInfo showLoadingSavegameDialog(boolean pubSer, + boolean single) { + LoadingSavegameDialog dialog + = new LoadingSavegameDialog(freeColClient, getFrame()); + return (canvas.showFreeColDialog(dialog, null)) ? dialog.getInfo() + : null; + } + + /** + * Show a panel containing the log file. + */ + public void showLogFilePanel() { + canvas.showSubPanel(new ErrorPanel(freeColClient), true); + + } + + /** + * Display the map generator options dialog. + * + * @param editable Should these options be editable. + * @return The {@code OptionGroup} as edited. + */ + public OptionGroup showMapGeneratorOptionsDialog(boolean editable) { + MapGeneratorOptionsDialog dialog + = new MapGeneratorOptionsDialog(freeColClient, getFrame(), + editable); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Display the map size dialog. + * + * @return The response returned by the dialog. + */ + public Dimension showMapSizeDialog() { + MapSizeDialog dialog = new MapSizeDialog(freeColClient, getFrame()); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Displays a number of ModelMessages. + * + * @param messages The {@code ModelMessage}s to display. + */ + public void showModelMessages(List messages) { + if (messages.isEmpty()) return; + final Game game = freeColClient.getGame(); + int n = messages.size(); + String[] texts = new String[n]; + FreeColObject[] fcos = new FreeColObject[n]; + ImageIcon[] icons = new ImageIcon[n]; + Tile tile = null; + for (int i = 0; i < n; i++) { + ModelMessage m = messages.get(i); + texts[i] = Messages.message(m); + fcos[i] = game.getMessageSource(m); + icons[i] = createObjectImageIcon(game.getMessageDisplay(m)); + if (tile == null && fcos[i] instanceof Location) { + tile = ((Location)fcos[i]).getTile(); + } + } + + InformationPanel panel + = new InformationPanel(freeColClient, texts, fcos, icons); + canvas.showFreeColPanel(panel, tile, true); + } + + /** + * Display the monarch dialog. + * + * @param action The {@code MonarchAction} underway. + * @param tmpl The {@code StringTemplate} describing the + * situation. + * @param monarchKey The resource key for the monarch image. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showMonarchDialog(MonarchAction action, + StringTemplate tmpl, String monarchKey, + DialogHandler handler) { + MonarchDialog dialog + = new MonarchDialog(freeColClient, getFrame(), + action, tmpl, monarchKey); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, null, handler)); + } + + /** + * Display a dialog to set a new name for something. + * + * @param tmpl A {@code StringTemplate} for the message + * to explain the dialog. + * @param defaultName The default name. + * @param unit The {@code Unit} discovering it. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showNamingDialog(StringTemplate tmpl, String defaultName, + Unit unit, DialogHandler handler) { + FreeColStringInputDialog dialog + = new FreeColStringInputDialog(freeColClient, getFrame(), false, + tmpl, defaultName, "ok", null); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, unit.getTile(), handler)); + } + + /** + * Display a dialog to handle a native demand to a colony. + * + * @param unit The demanding {@code Unit}. + * @param colony The {@code Colony} being demanded of. + * @param type The {@code GoodsType} demanded (null for gold). + * @param amount The amount of goods demanded. + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showNativeDemandDialog(Unit unit, Colony colony, + GoodsType type, int amount, + DialogHandler handler) { + NativeDemandDialog dialog + = new NativeDemandDialog(freeColClient, getFrame(), + unit, colony, type, amount); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, unit.getTile(), handler)); + } + + /** + * Displays the {@code NegotiationDialog}. + * + * @param our Our {@code FreeColGameObject} that is negotiating. + * @param other The other {@code FreeColGameObject}. + * @param agreement The current {@code DiplomaticTrade} agreement. + * @param comment An optional {@code StringTemplate} containing a + * commentary message. + * @return An updated agreement. + */ + public DiplomaticTrade showNegotiationDialog(FreeColGameObject our, + FreeColGameObject other, + DiplomaticTrade agreement, + StringTemplate comment) { + if ((!(our instanceof Unit) && !(our instanceof Colony)) + || (!(other instanceof Unit) && !(other instanceof Colony)) + || (our instanceof Colony && other instanceof Colony)) { + throw new RuntimeException("Bad DTD args: " + our + ", " + other); + } + NegotiationDialog dtd + = new NegotiationDialog(freeColClient, getFrame(), + our, other, agreement, comment); + return canvas.showFreeColDialog(dtd, ((Location)our).getTile()); + } + + /** + * Display the NewPanel for a given optional specification. + * + * @param specification The {@code Specification} to use. + */ + public void showNewPanel(Specification specification) { + NewPanel panel + = new NewPanel(freeColClient, specification); + canvas.showSubPanel(panel, false); + } + + /** + * Display the parameters dialog. + * + * @return The response returned by the dialog. + */ + public Parameters showParametersDialog() { + ParametersDialog dialog + = new ParametersDialog(freeColClient, getFrame()); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Display a dialog to confirm a combat. + * + * @param attacker The attacker {@code Unit}. + * @param defender The defender. + * @param tile A {@code Tile} to make visible. + * @return True if the combat is to proceed. + */ + public boolean showPreCombatDialog(Unit attacker, + FreeColGameObject defender, + Tile tile) { + PreCombatDialog dialog + = new PreCombatDialog(freeColClient, getFrame(), + attacker, defender); + return canvas.showFreeColDialog(dialog, tile); + } + + /** + * Displays the purchase panel. + */ + public void showPurchasePanel() { + PurchasePanel panel + = canvas.getExistingFreeColPanel(PurchasePanel.class); + if (panel == null) { + panel = new PurchasePanel(freeColClient); + panel.update(); + canvas.showFreeColPanel(panel, null, false); + } + } + + /** + * Displays the recruit panel. + */ + public void showRecruitPanel() { + RecruitPanel panel + = canvas.getExistingFreeColPanel(RecruitPanel.class); + if (panel == null) { + panel = new RecruitPanel(freeColClient); + canvas.showFreeColPanel(panel, null, false); + } + } + + /** + * Display the labour detail panel. + * + * @param unitType The {@code UnitType} to display. + * @param data The labour data. + * @param unitCount A map of unit distribution. + * @param colonies The list of player {@code Colony}s. + */ + public void showReportLabourDetailPanel(UnitType unitType, + Map> data, + TypeCountMap unitCount, List colonies) { + ReportLabourDetailPanel panel + = new ReportLabourDetailPanel(freeColClient, unitType, data, + unitCount, colonies); + panel.initialize(); + canvas.showSubPanel(panel, true); + } + + /** + * Display the river style dialog. + * + * @param styles The river styles a choice is made from. + * @return The response returned by the dialog. + */ + public String showRiverStyleDialog(List styles) { + RiverStyleDialog dialog + = new RiverStyleDialog(freeColClient, getFrame(), styles); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Displays a dialog where the user may choose a filename. + * + * @param directory The directory containing the files in which + * the user may overwrite. + * @param defaultName Default filename for the savegame. + * @return The selected {@code File}. + */ + public File showSaveDialog(File directory, String defaultName) { + String extension = lastPart(defaultName, "."); + FileFilter[] filters = new FileFilter[] { + FreeColDataFile.getFileFilter(extension) + }; + SaveDialog dialog + = new SaveDialog(freeColClient, getFrame(), + directory, filters, defaultName); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Display the scale map size dialog. + * + * @return The response returned by the dialog. + */ + public Dimension showScaleMapSizeDialog() { + ScaleMapSizeDialog dialog + = new ScaleMapSizeDialog(freeColClient, getFrame()); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Display the select-amount dialog. + * + * @param goodsType The {@code GoodsType} to select an amount of. + * @param available The amount of goods available. + * @param defaultAmount The amount to select to start with. + * @param needToPay If true, check the player has sufficient funds. + * @return The amount selected. + */ + public int showSelectAmountDialog(GoodsType goodsType, int available, + int defaultAmount, boolean needToPay) { + FreeColDialog dialog + = new SelectAmountDialog(freeColClient, getFrame(), + goodsType, available, + defaultAmount, needToPay); + Integer result = canvas.showFreeColDialog(dialog, null); + return (result == null) ? -1 : result; + } + + /** + * Display a dialog allowing the user to select a destination for + * a given unit. + * + * @param unit The {@code Unit} to select a destination for. + * @return A destination for the unit, or null. + */ + public Location showSelectDestinationDialog(Unit unit) { + SelectDestinationDialog dialog + = new SelectDestinationDialog(freeColClient, getFrame(), + unit); + return canvas.showFreeColDialog(dialog, unit.getTile()); + } + + /** + * Display the select-tribute-amount dialog. + * + * @param question a {@code stringtemplate} describing the + * amount of tribute to demand. + * @param maximum The maximum amount available. + * @return The amount selected. + */ + public int showSelectTributeAmountDialog(StringTemplate question, + int maximum) { + FreeColDialog dialog + = new SelectTributeAmountDialog(freeColClient, getFrame(), + question, maximum); + Integer result = canvas.showFreeColDialog(dialog, null); + return (result == null) ? -1 : result; + } + + /** + * Display the statistics panel. + * + * @param serverStats A map of server statistics key,value pairs. + * @param clientStats A map of client statistics key,value pairs. + */ + public void showStatisticsPanel(Map serverStats, + Map clientStats) { + StatisticsPanel panel + = new StatisticsPanel(freeColClient, serverStats, clientStats); + canvas.showSubPanel(panel, true); + } + + /** + * Display the tile panel for a given tile. + * + * @param tile The {@code Tile} to display. + */ + public void showTilePanel(Tile tile) { + if (tile == null || !tile.isExplored()) return; + TilePanel panel = new TilePanel(freeColClient, tile); + canvas.showSubPanel(panel, false); + } + + /** + * Display the trade route input panel for a given trade route. + * + * @param newRoute The {@code TradeRoute} to display. + * @return The {@code TradeRouteInputPanel}. + */ + public TradeRouteInputPanel showTradeRouteInputPanel(TradeRoute newRoute) { + TradeRouteInputPanel panel + = new TradeRouteInputPanel(freeColClient, newRoute); + canvas.showSubPanel(panel, null, true); + return panel; + } + + /** + * Display a panel to select a trade route for a unit. + * + * @param unit An optional {@code Unit} to select a trade route for. + */ + public void showTradeRoutePanel(Unit unit) { + TradeRoutePanel panel = new TradeRoutePanel(freeColClient, unit); + canvas.showFreeColPanel(panel, (unit == null) ? null : unit.getTile(), true); + } + + /** + * Displays the training panel. + */ + public void showTrainPanel() { + TrainPanel panel + = canvas.getExistingFreeColPanel(TrainPanel.class); + if (panel == null) { + panel = new TrainPanel(freeColClient); + panel.update(); + canvas.showFreeColPanel(panel, null, false); + } + } + + /** + * Display the victory dialog. + * + * @param handler A {@code DialogHandler} for the dialog response. + */ + public void showVictoryDialog(DialogHandler handler) { + VictoryDialog dialog + = new VictoryDialog(freeColClient, getFrame()); + SwingUtilities.invokeLater( + new DialogCallback<>(dialog, null, handler)); + } + + /** + * Display the warehouse dialog for a colony. + * + * Run out of ColonyPanel, so the tile is already displayed. + * + * @param colony The {@code Colony} to display. + * @return The response returned by the dialog. + */ + public boolean showWarehouseDialog(Colony colony) { + WarehouseDialog dialog + = new WarehouseDialog(freeColClient, getFrame(), + colony); + return canvas.showFreeColDialog(dialog, null); + } + + /** + * Display the production of a unit. + * + * @param unit The {@code Unit} to display. + */ + public void showWorkProductionPanel(Unit unit) { + WorkProductionPanel panel + = new WorkProductionPanel(freeColClient, unit); + canvas.showSubPanel(panel, true); + } + + /** + * Update all panels derived from the EuropePanel. + */ + public void updateEuropeanSubpanels() { + for (Class c: EUROPE_CLASSES) { + FreeColPanel p = canvas.getExistingFreeColPanel(c); + if (p != null) { + // TODO: remember how to write generic code, avoid introspection + try { + Introspector.invokeVoidMethod(p, "update"); + } catch (Exception e) { + ; // "can not happen" + } + } + } + } + + // Singleton specialist reports + + public void showReportCargoPanel() { + ReportCargoPanel panel + = canvas.getExistingFreeColPanel(ReportCargoPanel.class); + if (panel == null) { + panel = new ReportCargoPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportColonyPanel() { + boolean compact; + try { + compact = freeColClient.getClientOptions() + .getInteger(ClientOptions.COLONY_REPORT) + == ClientOptions.COLONY_REPORT_COMPACT; + } catch (Exception e) { + compact = false; + } + ReportPanel panel = (compact) + ? canvas.getExistingFreeColPanel(ReportCompactColonyPanel.class) + : canvas.getExistingFreeColPanel(ReportClassicColonyPanel.class); + if (panel == null) { + panel = (compact) + ? new ReportCompactColonyPanel(freeColClient) + : new ReportClassicColonyPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportContinentalCongressPanel() { + ReportContinentalCongressPanel panel + = canvas.getExistingFreeColPanel(ReportContinentalCongressPanel.class); + if (panel == null) { + panel = new ReportContinentalCongressPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportEducationPanel() { + ReportEducationPanel panel + = canvas.getExistingFreeColPanel(ReportEducationPanel.class); + if (panel == null) { + panel = new ReportEducationPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportExplorationPanel() { + ReportExplorationPanel panel + = canvas.getExistingFreeColPanel(ReportExplorationPanel.class); + if (panel == null) { + panel = new ReportExplorationPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportForeignAffairPanel() { + ReportForeignAffairPanel panel + = canvas.getExistingFreeColPanel(ReportForeignAffairPanel.class); + if (panel == null) { + panel = new ReportForeignAffairPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportHistoryPanel() { + ReportHistoryPanel panel + = canvas.getExistingFreeColPanel(ReportHistoryPanel.class); + if (panel == null) { + panel = new ReportHistoryPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportIndianPanel() { + ReportIndianPanel panel + = canvas.getExistingFreeColPanel(ReportIndianPanel.class); + if (panel == null) { + panel = new ReportIndianPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportLabourPanel() { + ReportLabourPanel panel + = canvas.getExistingFreeColPanel(ReportLabourPanel.class); + if (panel == null) { + panel = new ReportLabourPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportMilitaryPanel() { + ReportMilitaryPanel panel + = canvas.getExistingFreeColPanel(ReportMilitaryPanel.class); + if (panel == null) { + panel = new ReportMilitaryPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportNavalPanel() { + ReportNavalPanel panel + = canvas.getExistingFreeColPanel(ReportNavalPanel.class); + if (panel == null) { + panel = new ReportNavalPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportProductionPanel() { + ReportProductionPanel panel + = canvas.getExistingFreeColPanel(ReportProductionPanel.class); + if (panel == null) { + panel = new ReportProductionPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportReligiousPanel() { + ReportReligiousPanel panel + = canvas.getExistingFreeColPanel(ReportReligiousPanel.class); + if (panel == null) { + panel = new ReportReligiousPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportRequirementsPanel() { + ReportRequirementsPanel panel + = canvas.getExistingFreeColPanel(ReportRequirementsPanel.class); + if (panel == null) { + panel = new ReportRequirementsPanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + public void showReportTradePanel() { + ReportTradePanel panel + = canvas.getExistingFreeColPanel(ReportTradePanel.class); + if (panel == null) { + panel = new ReportTradePanel(freeColClient); + canvas.showSubPanel(panel, true); + } + } + + /** + * Show the turn report. + * + * @param messages The {@code ModelMessage}s to show. + */ + public void showReportTurnPanel(List messages) { + ReportTurnPanel panel + = canvas.getExistingFreeColPanel(ReportTurnPanel.class); + if (panel == null) { + panel = new ReportTurnPanel(freeColClient, messages); + canvas.showSubPanel(panel, true); + } else { + panel.setMessages(messages); + } + } +} diff --git a/src/net/sf/freecol/client/gui/action/ChangeWindowedModeAction.java b/src/net/sf/freecol/client/gui/action/ChangeWindowedModeAction.java index 240dc7b262..d4c520b112 100644 --- a/src/net/sf/freecol/client/gui/action/ChangeWindowedModeAction.java +++ b/src/net/sf/freecol/client/gui/action/ChangeWindowedModeAction.java @@ -43,32 +43,6 @@ public ChangeWindowedModeAction(FreeColClient freeColClient) { } - // Override SelectableAction - - /** - * {@inheritDoc} - */ - @Override - public boolean shouldBeSelected() { - final GUI gui = getGUI(); - return !(gui == null || gui.isWindowed()) - && super.shouldBeSelected(); - } - - - // Override FreeColAction - - /** - * {@inheritDoc} - */ - @Override - public boolean shouldBeEnabled() { - final GUI gui = getGUI(); - return !(gui == null || gui.isShowingSubPanel()) - && super.shouldBeEnabled(); - } - - // Interface ActionListener /** diff --git a/src/net/sf/freecol/client/gui/action/DebugAction.java b/src/net/sf/freecol/client/gui/action/DebugAction.java index 597b21d3b4..b334c7fdbe 100644 --- a/src/net/sf/freecol/client/gui/action/DebugAction.java +++ b/src/net/sf/freecol/client/gui/action/DebugAction.java @@ -45,7 +45,7 @@ public DebugAction(FreeColClient freeColClient) { super(freeColClient, id); setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, - KeyEvent.SHIFT_MASK | KeyEvent.CTRL_MASK)); + KeyEvent.SHIFT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)); } diff --git a/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java b/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java index cebd52d83b..983ff7f12b 100644 --- a/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java +++ b/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java @@ -69,7 +69,7 @@ public DisplayTileTextAction(FreeColClient freeColClient, ClientOptions.DISPLAY_TILE_TEXT); display = type; setAccelerator(KeyStroke.getKeyStroke(accelerators[type.ordinal()], - KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK)); + KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); setSelected(shouldBeSelected()); } diff --git a/src/net/sf/freecol/client/gui/action/FreeColAction.java b/src/net/sf/freecol/client/gui/action/FreeColAction.java index 8a8cb9059c..0a696479f9 100644 --- a/src/net/sf/freecol/client/gui/action/FreeColAction.java +++ b/src/net/sf/freecol/client/gui/action/FreeColAction.java @@ -86,8 +86,9 @@ public InnerMenuKeyListener() { public void menuKeyPressed(MenuKeyEvent e) { if (e.getKeyCode() == mnemonic) { - ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), (String) getValue(Action.NAME), - e.getModifiers()); + ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), + (String) getValue(Action.NAME), + e.getModifiersEx()); actionPerformed(ae); e.consume(); @@ -338,8 +339,8 @@ protected boolean shouldBeEnabled() { * {@link #shouldBeEnabled}. */ public void update() { - boolean b = shouldBeEnabled(); - if (isEnabled() != b) setEnabled(b); + boolean b = this.shouldBeEnabled(); + if (this.isEnabled() != b) this.setEnabled(b); } diff --git a/src/net/sf/freecol/client/gui/action/SelectableAction.java b/src/net/sf/freecol/client/gui/action/SelectableAction.java index 6137d19fef..e54cb092d8 100644 --- a/src/net/sf/freecol/client/gui/action/SelectableAction.java +++ b/src/net/sf/freecol/client/gui/action/SelectableAction.java @@ -112,17 +112,6 @@ protected boolean shouldBeSelected() { // Override FreeColAction - /** - * {@inheritDoc} - */ - @Override - protected boolean shouldBeEnabled() { - final Player player = getFreeColClient().getMyPlayer(); - return player != null && player.getNewModelMessages().isEmpty() - && getFreeColClient().getGame() != null - && super.shouldBeEnabled(); - } - /** * {@inheritDoc} */ diff --git a/src/net/sf/freecol/client/gui/dialog/ConfirmDeclarationDialog.java b/src/net/sf/freecol/client/gui/dialog/ConfirmDeclarationDialog.java index f378722fcf..185548c867 100644 --- a/src/net/sf/freecol/client/gui/dialog/ConfirmDeclarationDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/ConfirmDeclarationDialog.java @@ -128,7 +128,7 @@ protected void setLabelValues(JLabel c, T value) { // based on the flag of Brazil, particularly the Provisional // Flag of Republic of the United States of Brazil (November - // 15–19, 1889) + // 15-19, 1889) public static final Flag PORTUGUESE_FLAG = new Flag(Background.FESSES, Decoration.NONE, UnionPosition.CANTON) .setUnionColor(new Color(62, 64, 149)) diff --git a/src/net/sf/freecol/client/gui/dialog/FreeColChoiceDialog.java b/src/net/sf/freecol/client/gui/dialog/FreeColChoiceDialog.java index f14bf5d77f..0bd13455f9 100644 --- a/src/net/sf/freecol/client/gui/dialog/FreeColChoiceDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/FreeColChoiceDialog.java @@ -55,7 +55,7 @@ protected FreeColChoiceDialog(FreeColClient freeColClient, JFrame frame) { * @param freeColClient The {@code FreeColClient} for the game. * @param frame The owner frame. * @param modal True if this dialog should be modal. - * @param obj An object that explains the choice for the user. + * @param tmpl A {@code StringTemplate} with an explanatory message. * @param icon An optional icon to display. * @param cancelKey Key for the text of the optional cancel button. * @param choices A list of {@code ChoiceItem}s to create buttons for. diff --git a/src/net/sf/freecol/client/gui/menu/DebugMenu.java b/src/net/sf/freecol/client/gui/menu/DebugMenu.java index 46f47cc722..3e718b936d 100644 --- a/src/net/sf/freecol/client/gui/menu/DebugMenu.java +++ b/src/net/sf/freecol/client/gui/menu/DebugMenu.java @@ -321,9 +321,15 @@ private void buildDebugMenu() { final JMenuItem compareMaps = Utility.localizedMenuItem("menuBar.debug.compareMaps"); compareMaps.setOpaque(false); //compareMaps.setMnemonic(KeyEvent.VK_C); + compareMaps.setAccelerator(KeyStroke.getKeyStroke('C', - Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() - | InputEvent.ALT_MASK)); + // FIXME: In Java 7 we used + // Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() + // instead of CTRL_DOWN_MASK, but this is now deprecated + // and the replacement getMenuShortcutKeyMaskEx() is not + // present in Java 7. + InputEvent.CTRL_DOWN_MASK + | InputEvent.ALT_DOWN_MASK)); this.add(compareMaps); compareMaps.addActionListener((ActionEvent ae) -> { DebugUtils.checkDesyncAction(freeColClient); diff --git a/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java b/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java index db2d60bd30..0260ccbe3d 100644 --- a/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java +++ b/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java @@ -137,7 +137,7 @@ private static void createAndShowGUI() { FreeColClient client = FreeColClient.startTestClient(null); FreeColFrame frame = new FreeColFrame(client, GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(), - null, null, true, null); + null, true, null); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //Create and set up the content pane. diff --git a/src/net/sf/freecol/client/gui/option/FreeColActionUI.java b/src/net/sf/freecol/client/gui/option/FreeColActionUI.java index e73dcd489e..10f438dab4 100644 --- a/src/net/sf/freecol/client/gui/option/FreeColActionUI.java +++ b/src/net/sf/freecol/client/gui/option/FreeColActionUI.java @@ -24,6 +24,7 @@ import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; @@ -134,7 +135,7 @@ public static String getHumanKeyStrokeText(KeyStroke keyStroke) { return " "; } - String s = KeyEvent.getKeyModifiersText(keyStroke.getModifiers()); + String s = InputEvent.getModifiersExText(keyStroke.getModifiers()); if (!s.isEmpty()) s += "+"; return s + KeyEvent.getKeyText(keyStroke.getKeyCode()); } @@ -246,7 +247,8 @@ public void keyTyped(KeyEvent e) { /* No such event */ } @Override public void keyReleased(KeyEvent e) { - KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers()); + KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), + e.getModifiersEx()); if (FreeColActionUI.this.optionGroupUI != null) { FreeColActionUI.this.optionGroupUI.removeKeyStroke(ks); } diff --git a/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java b/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java index 6da0c9bd8c..30af6339f9 100644 --- a/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java +++ b/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java @@ -172,7 +172,7 @@ public Component getListCellRendererComponent(JList list, JButton cancelButton = Utility.localizedButton("cancel"); cancelButton.addActionListener((ae) -> - getGUI().getCanvas().removeTradeRoutePanel(this)); + getGUI().removeTradeRoutePanel(this)); setCancelComponent(cancelButton); updateButtons(); diff --git a/src/net/sf/freecol/client/gui/panel/Utility.java b/src/net/sf/freecol/client/gui/panel/Utility.java index 8e4cb9bdd8..208f181e07 100644 --- a/src/net/sf/freecol/client/gui/panel/Utility.java +++ b/src/net/sf/freecol/client/gui/panel/Utility.java @@ -631,8 +631,9 @@ public static JTextArea localizedTextArea(StringTemplate template, /** * Get a panel with a localized message and icon. * - * @param icon An ImageIcon to use. - * @param template The StringTemplate to use. + * @param template The {@code StringTemplate} to use. + * @param icon An {@code ImageIcon} to use. + * @return The resulting {@code JPanel}. */ public static JPanel localizedTextPanel(StringTemplate template, ImageIcon icon) { diff --git a/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxUI.java b/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxUI.java index 74087ae4a1..37b6a0c084 100644 --- a/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxUI.java +++ b/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxUI.java @@ -42,6 +42,7 @@ public void installUI(JComponent c) { c.setOpaque(false); } + @SuppressWarnings("unchecked") @Override protected ListCellRenderer createRenderer() { return new FreeColComboBoxRenderer(); diff --git a/src/net/sf/freecol/common/debug/DebugUtils.java b/src/net/sf/freecol/common/debug/DebugUtils.java index 88f9805d12..eafc296c22 100644 --- a/src/net/sf/freecol/common/debug/DebugUtils.java +++ b/src/net/sf/freecol/common/debug/DebugUtils.java @@ -1008,6 +1008,7 @@ public static void setColonyGoods(final FreeColClient freeColClient, /** * Set COMMS logging. * + * @param freeColClient The {@code FreeColClient} for the game. * @param log If true, enable COMMS logging. */ public static void setCommsLogging(final FreeColClient freeColClient, diff --git a/src/net/sf/freecol/common/model/Map.java b/src/net/sf/freecol/common/model/Map.java index e664ac2ee7..d7a183d90f 100644 --- a/src/net/sf/freecol/common/model/Map.java +++ b/src/net/sf/freecol/common/model/Map.java @@ -271,14 +271,14 @@ public String toString() { /** * The latitude of the northern edge of the map. A negative value * indicates northern latitude, a positive value southern - * latitude. Thus, -30 equals 30°N, and 40 equals 40°S. + * latitude. Thus, -30 equals 30 degrees N, and 40 equals 40 degrees S. */ private int minimumLatitude = -90; /** * The latitude of the southern edge of the map. A negative value * indicates northern latitude, a positive value southern - * latitude. Thus, -30 equals 30°N, and 40 equals 40°S. + * latitude. Thus, -30 equals 30 degrees N, and 40 equals 40 degrees S. */ private int maximumLatitude = 90; diff --git a/src/net/sf/freecol/common/util/Introspector.java b/src/net/sf/freecol/common/util/Introspector.java index 127b9e796b..369844f875 100644 --- a/src/net/sf/freecol/common/util/Introspector.java +++ b/src/net/sf/freecol/common/util/Introspector.java @@ -425,4 +425,19 @@ public static T invokeMethod(Object object, String methodName, return returnClass.cast(object.getClass().getMethod(methodName) .invoke(object)); } + + /** + * Invoke an object void method by name. + * + * @param object The base object. + * @param methodName The name of the method to invoke. + * @exception IllegalAccessException if the method exists but is hidden. + * @exception InvocationTargetException if the target can not be invoked. + * @exception NoSuchMethodException if the invocation fails. + */ + public static void invokeVoidMethod(Object object, String methodName) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + object.getClass().getMethod(methodName).invoke(object); + } } diff --git a/src/net/sf/freecol/common/util/Utils.java b/src/net/sf/freecol/common/util/Utils.java index 8c60fbfb31..bca6c8940b 100644 --- a/src/net/sf/freecol/common/util/Utils.java +++ b/src/net/sf/freecol/common/util/Utils.java @@ -19,6 +19,10 @@ package net.sf.freecol.common.util; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.MouseInfo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -375,4 +379,23 @@ public static void garbageCollect() { public static boolean isHeadless() { return "true".equals(System.getProperty("java.awt.headless", "false")); } + + /** + * Get a good screen device for starting FreeCol. + * + * @return A screen device, or null if none available + * (as in headless mode). + */ + public static GraphicsDevice getGoodGraphicsDevice() { + try { + return MouseInfo.getPointerInfo().getDevice(); + } catch (HeadlessException he) {} + + try { + final GraphicsEnvironment lge + = GraphicsEnvironment.getLocalGraphicsEnvironment(); + return lge.getDefaultScreenDevice(); + } catch (HeadlessException he) {} + return null; + } } diff --git a/test/src/net/sf/freecol/common/model/SerializationTest.java b/test/src/net/sf/freecol/common/model/SerializationTest.java index 6a3367ddd1..189dccbac2 100644 --- a/test/src/net/sf/freecol/common/model/SerializationTest.java +++ b/test/src/net/sf/freecol/common/model/SerializationTest.java @@ -114,22 +114,10 @@ public void testValidation() throws Exception { ServerTestHelper.stopServerGame(); } - public void testMapAfrica() throws Exception { - validateMap("data/maps/Africa.fsm"); - } - - public void testMapAustralia() throws Exception { - validateMap("data/maps/Australia.fsm"); - } - - public void testMapAmerica() throws Exception { - validateMap("data/maps/America_large.fsm"); - validateMap("data/maps/South_America.fsm"); - } - - public void testMapCaribbean() throws Exception { - validateMap("data/maps/Caribbean_basin.fsm"); - validateMap("data/maps/Caribbean_large.fsm"); + public void testStandardMaps() throws Exception { + for (String name : FreeColTestCase.STANDARD_MAPS) { + validateMap(name); + } } public void testStringTemplate() throws Exception { diff --git a/test/src/net/sf/freecol/server/generator/MapGeneratorTest.java b/test/src/net/sf/freecol/server/generator/MapGeneratorTest.java index fb1c979cae..39d682edca 100644 --- a/test/src/net/sf/freecol/server/generator/MapGeneratorTest.java +++ b/test/src/net/sf/freecol/server/generator/MapGeneratorTest.java @@ -183,23 +183,40 @@ public void testIndianCapital() { * Make sure we can import all distributed maps. */ public void testImportMap() { - Game game = getStandardGame(); - final Specification spec = game.getSpecification(); - MapGenerator gen = new SimpleMapGenerator(new Random(1)); Map importMap = null; - for (File importFile : FreeColDirectories.getMapFileList()) { + List mapFiles = new ArrayList<>(); + if (true) { + // We now have too many maps to test comprehensively, so + // we will just test the standard (old) maps for now + for (String name : FreeColTestCase.STANDARD_MAPS) { + mapFiles.add(new File(name)); + } + } else { + // This test all the maps + mapFiles.addAll(FreeColDirectories.getMapFileList()); + } + for (File importFile : mapFiles) { + Game game = getStandardGame(); + Specification spec = game.getSpecification(); spec.setFile(MapGeneratorOptions.IMPORT_FILE, importFile); + System.gc(); // Try to clean up before reading a big map try { importMap = FreeColServer.readMap(importFile, spec); } catch (FreeColException|IOException|XMLStreamException ex) { fail("Map read of " + importFile.getName() + " failed: " + ex.toString()); } - assertNotNull(gen.generateMap(game, importMap, new LogBuilder(-1))); + try { + assertNotNull(gen.generateMap(game, importMap, + new LogBuilder(-1))); + } catch (Exception ex) { + fail("Map generate of " + importFile.getName() + " failed: " + + ex.toString()); + } + // Clear import file option from a standard spec! + spec.setFile(MapGeneratorOptions.IMPORT_FILE, null); } - // Clear import file option - spec.setFile(MapGeneratorOptions.IMPORT_FILE, null); } public void testRegions() { diff --git a/test/src/net/sf/freecol/util/test/FreeColTestCase.java b/test/src/net/sf/freecol/util/test/FreeColTestCase.java index 9e69640df0..c76f7d1c85 100644 --- a/test/src/net/sf/freecol/util/test/FreeColTestCase.java +++ b/test/src/net/sf/freecol/util/test/FreeColTestCase.java @@ -64,6 +64,14 @@ */ public class FreeColTestCase extends TestCase { + /** We now have lots of maps, restrict testing to just the old ones. */ + public static String[] STANDARD_MAPS = { + "data/maps/M_Africa_Gilolat.fsm", + "data/maps/S_AustraliaOceania_Gilolat.fsm", + "data/maps/L_America_JsTheDude.fsm", + "data/maps/S_Caribbean_Phil.fsm" + }; + private static java.util.Map specifications = new HashMap<>();